ia64/xen-unstable
changeset 5922:577d1c7b47a9
PDB: process targets
author | ach61@arcadians.cl.cam.ac.uk |
---|---|
date | Thu Jul 28 21:28:23 2005 +0000 (2005-07-28) |
parents | 501a70f3ae96 |
children | dd1c092a7ee2 |
files | linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c tools/debugger/libxendebug/xendebug.c tools/debugger/pdb/PDB.ml tools/debugger/pdb/Process.ml tools/debugger/pdb/Process.mli tools/debugger/pdb/debugger.ml tools/debugger/pdb/linux-2.6-module/debug.c tools/debugger/pdb/linux-2.6-module/module.c tools/debugger/pdb/linux-2.6-module/pdb_module.h tools/debugger/pdb/pdb_caml_process.c tools/debugger/pdb/pdb_caml_xcs.c tools/debugger/pdb/readme |
line diff
1.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c Thu Jul 28 12:34:45 2005 +0000 1.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c Thu Jul 28 21:28:23 2005 +0000 1.3 @@ -90,7 +90,9 @@ asmlinkage void machine_check(void); 1.4 1.5 static int kstack_depth_to_print = 24; 1.6 struct notifier_block *i386die_chain; 1.7 -static DEFINE_SPINLOCK(die_notifier_lock); 1.8 +DEFINE_SPINLOCK(die_notifier_lock); 1.9 +EXPORT_SYMBOL(die_notifier_lock); 1.10 +EXPORT_SYMBOL(i386die_chain); 1.11 1.12 int register_die_notifier(struct notifier_block *nb) 1.13 {
2.1 --- a/tools/debugger/libxendebug/xendebug.c Thu Jul 28 12:34:45 2005 +0000 2.2 +++ b/tools/debugger/libxendebug/xendebug.c Thu Jul 28 21:28:23 2005 +0000 2.3 @@ -42,7 +42,6 @@ typedef struct bwcpoint 2.4 struct list_head list; 2.5 memory_t address; 2.6 u32 domain; 2.7 - u16 vcpu; 2.8 u8 old_value; /* old value for software bkpt */ 2.9 } bwcpoint_t, *bwcpoint_p; 2.10
3.1 --- a/tools/debugger/pdb/PDB.ml Thu Jul 28 12:34:45 2005 +0000 3.2 +++ b/tools/debugger/pdb/PDB.ml Thu Jul 28 21:28:23 2005 +0000 3.3 @@ -138,9 +138,13 @@ let attach_debugger ctx = 3.4 3.5 let detach_debugger ctx = 3.6 match ctx with 3.7 - | Domain d -> Domain.detach_debugger (Domain.get_domain d) 3.8 - (Domain.get_vcpu d) 3.9 - | Process p -> Process.detach_debugger p 3.10 + | Domain d -> 3.11 + Domain.detach_debugger (Domain.get_domain d) 3.12 + (Domain.get_vcpu d); 3.13 + "OK" 3.14 + | Process p -> 3.15 + Process.detach_debugger p; 3.16 + raise No_reply 3.17 | _ -> raise (Unimplemented "detach debugger") 3.18 3.19 3.20 @@ -240,13 +244,21 @@ let write_register ctx register value = 3.21 let read_memory ctx addr len = 3.22 match ctx with 3.23 | Domain d -> Domain.read_memory d addr len 3.24 - | Process p -> Process.read_memory p addr len 3.25 + | Process p -> 3.26 + begin 3.27 + Process.read_memory p addr len; 3.28 + raise No_reply 3.29 + end 3.30 | _ -> raise (Unimplemented "read memory") 3.31 3.32 let write_memory ctx addr values = 3.33 match ctx with 3.34 | Domain d -> Domain.write_memory d addr values 3.35 - | Process p -> Process.write_memory p addr values 3.36 + | Process p -> 3.37 + begin 3.38 + Process.write_memory p addr values; 3.39 + raise No_reply 3.40 + end 3.41 | _ -> raise (Unimplemented "write memory") 3.42 3.43
4.1 --- a/tools/debugger/pdb/Process.ml Thu Jul 28 12:34:45 2005 +0000 4.2 +++ b/tools/debugger/pdb/Process.ml Thu Jul 28 21:28:23 2005 +0000 4.3 @@ -57,7 +57,7 @@ let attach_debugger proc_ctx dom_ctx = 4.4 external read_registers : context_t -> unit = "proc_read_registers" 4.5 external write_register : context_t -> register -> int32 -> unit = 4.6 "proc_write_register" 4.7 -external read_memory : context_t -> int32 -> int -> int list = 4.8 +external read_memory : context_t -> int32 -> int -> unit = 4.9 "proc_read_memory" 4.10 external write_memory : context_t -> int32 -> int list -> unit = 4.11 "proc_write_memory"
5.1 --- a/tools/debugger/pdb/Process.mli Thu Jul 28 12:34:45 2005 +0000 5.2 +++ b/tools/debugger/pdb/Process.mli Thu Jul 28 21:28:23 2005 +0000 5.3 @@ -29,7 +29,7 @@ val pause : context_t -> unit 5.4 5.5 val read_registers : context_t -> unit 5.6 val write_register : context_t -> register -> int32 -> unit 5.7 -val read_memory : context_t -> int32 -> int -> int list 5.8 +val read_memory : context_t -> int32 -> int -> unit 5.9 val write_memory : context_t -> int32 -> int list -> unit 5.10 5.11 val continue : context_t -> unit
6.1 --- a/tools/debugger/pdb/debugger.ml Thu Jul 28 12:34:45 2005 +0000 6.2 +++ b/tools/debugger/pdb/debugger.ml Thu Jul 28 21:28:23 2005 +0000 6.3 @@ -25,8 +25,7 @@ let exit_debugger () = 6.4 hash. It will be cleaned up with the socket is closed. 6.5 *) 6.6 let gdb_detach ctx = 6.7 - PDB.detach_debugger ctx; 6.8 - raise No_reply 6.9 + PDB.detach_debugger ctx 6.10 6.11 (** 6.12 Kill Command
7.1 --- a/tools/debugger/pdb/linux-2.6-module/debug.c Thu Jul 28 12:34:45 2005 +0000 7.2 +++ b/tools/debugger/pdb/linux-2.6-module/debug.c Thu Jul 28 21:28:23 2005 +0000 7.3 @@ -3,49 +3,54 @@ 7.4 * pdb debug functionality for processes. 7.5 */ 7.6 7.7 - 7.8 #include <linux/module.h> 7.9 +#include <linux/mm.h> 7.10 #include <linux/sched.h> 7.11 +#include <asm-i386/kdebug.h> 7.12 +#include <asm-xen/asm-i386/processor.h> 7.13 #include <asm-xen/asm-i386/ptrace.h> 7.14 #include <asm-xen/xen-public/xen.h> 7.15 - 7.16 #include "pdb_module.h" 7.17 +#include "pdb_debug.h" 7.18 7.19 -EXPORT_SYMBOL(pdb_attach); 7.20 -EXPORT_SYMBOL(pdb_detach); 7.21 +#define BWC_DEBUG 1 7.22 +#define BWC_INT3 3 7.23 +typedef struct bwcpoint /* break/watch/catch point */ 7.24 +{ 7.25 + struct list_head list; 7.26 + memory_t address; 7.27 + u32 domain; 7.28 + u32 process; 7.29 + u8 old_value; /* old value for software bkpt */ 7.30 + u8 type; /* BWC_??? */ 7.31 +} bwcpoint_t, *bwcpoint_p; 7.32 + 7.33 +static bwcpoint_t bwcpoint_list; 7.34 + 7.35 +void 7.36 +pdb_initialize_bwcpoint (void) 7.37 +{ 7.38 + memset((void *) &bwcpoint_list, 0, sizeof(bwcpoint_t)); 7.39 + INIT_LIST_HEAD(&bwcpoint_list.list); 7.40 + 7.41 + return; 7.42 +} 7.43 + 7.44 7.45 int 7.46 -pdb_attach (int pid) 7.47 +pdb_suspend (struct task_struct *target) 7.48 { 7.49 - struct task_struct *target; 7.50 u32 rc = 0; 7.51 7.52 - printk ("pdb attach: 0x%x\n", pid); 7.53 - 7.54 - read_lock(&tasklist_lock); 7.55 - target = find_task_by_pid(pid); 7.56 - if (target) 7.57 - get_task_struct(target); 7.58 - read_unlock(&tasklist_lock); 7.59 - 7.60 force_sig(SIGSTOP, target); /* force_sig_specific ??? */ 7.61 7.62 return rc; 7.63 } 7.64 7.65 int 7.66 -pdb_detach (int pid) 7.67 +pdb_resume (struct task_struct *target) 7.68 { 7.69 int rc = 0; 7.70 - struct task_struct *target; 7.71 - 7.72 - printk ("pdb detach: 0x%x\n", pid); 7.73 - 7.74 - read_lock(&tasklist_lock); 7.75 - target = find_task_by_pid(pid); 7.76 - if (target) 7.77 - get_task_struct(target); 7.78 - read_unlock(&tasklist_lock); 7.79 7.80 wake_up_process(target); 7.81 7.82 @@ -55,7 +60,6 @@ pdb_detach (int pid) 7.83 /* 7.84 * from linux-2.6.11/arch/i386/kernel/ptrace.c::getreg() 7.85 */ 7.86 - 7.87 static unsigned long 7.88 _pdb_get_register (struct task_struct *target, int reg) 7.89 { 7.90 @@ -65,20 +69,20 @@ static unsigned long 7.91 7.92 switch (reg) 7.93 { 7.94 - case FS: 7.95 + case LINUX_FS: 7.96 result = target->thread.fs; 7.97 break; 7.98 - case GS: 7.99 + case LINUX_GS: 7.100 result = target->thread.gs; 7.101 break; 7.102 - case DS: 7.103 - case ES: 7.104 - case SS: 7.105 - case CS: 7.106 + case LINUX_DS: 7.107 + case LINUX_ES: 7.108 + case LINUX_SS: 7.109 + case LINUX_CS: 7.110 result = 0xffff; 7.111 /* fall through */ 7.112 default: 7.113 - if (reg > GS) 7.114 + if (reg > LINUX_GS) 7.115 reg -= 2; 7.116 7.117 offset = reg * sizeof(long); 7.118 @@ -91,17 +95,51 @@ static unsigned long 7.119 return result; 7.120 } 7.121 7.122 +/* 7.123 + * from linux-2.6.11/arch/i386/kernel/ptrace.c::putreg() 7.124 + */ 7.125 +static void 7.126 +_pdb_set_register (struct task_struct *target, int reg, unsigned long val) 7.127 +{ 7.128 + unsigned long offset; 7.129 + unsigned char *stack; 7.130 + unsigned long value = val; 7.131 + 7.132 + switch (reg) 7.133 + { 7.134 + case LINUX_FS: 7.135 + target->thread.fs = value; 7.136 + return; 7.137 + case LINUX_GS: 7.138 + target->thread.gs = value; 7.139 + return; 7.140 + case LINUX_DS: 7.141 + case LINUX_ES: 7.142 + value &= 0xffff; 7.143 + break; 7.144 + case LINUX_SS: 7.145 + case LINUX_CS: 7.146 + value &= 0xffff; 7.147 + break; 7.148 + case LINUX_EFL: 7.149 + break; 7.150 + } 7.151 + 7.152 + if (reg > LINUX_GS) 7.153 + reg -= 2; 7.154 + offset = reg * sizeof(long); 7.155 + offset -= sizeof(struct pt_regs); 7.156 + stack = (unsigned char *)target->thread.esp0; 7.157 + stack += offset; 7.158 + *(unsigned long *) stack = value; 7.159 + 7.160 + return; 7.161 +} 7.162 + 7.163 int 7.164 -pdb_read_register (int pid, pdb_op_rd_regs_p op) 7.165 +pdb_read_registers (struct task_struct *target, pdb_op_rd_regs_p op) 7.166 { 7.167 int rc = 0; 7.168 - struct task_struct *target; 7.169 - 7.170 - read_lock(&tasklist_lock); 7.171 - target = find_task_by_pid(pid); 7.172 - if (target) 7.173 - get_task_struct(target); 7.174 - read_unlock(&tasklist_lock); 7.175 7.176 op->reg[ 0] = _pdb_get_register(target, LINUX_EAX); 7.177 op->reg[ 1] = _pdb_get_register(target, LINUX_ECX); 7.178 @@ -124,59 +162,250 @@ pdb_read_register (int pid, pdb_op_rd_re 7.179 return rc; 7.180 } 7.181 7.182 -/* 7.183 - * from linux-2.6.11/arch/i386/kernel/ptrace.c::putreg() 7.184 - */ 7.185 +int 7.186 +pdb_write_register (struct task_struct *target, pdb_op_wr_reg_p op) 7.187 +{ 7.188 + int rc = 0; 7.189 + 7.190 + _pdb_set_register(target, op->reg, op->value); 7.191 + 7.192 + return rc; 7.193 +} 7.194 + 7.195 +int 7.196 +pdb_access_memory (struct task_struct *target, unsigned long address, 7.197 + void *buffer, int length, int write) 7.198 +{ 7.199 + int rc = 0; 7.200 + 7.201 + access_process_vm(target, address, buffer, length, write); 7.202 + 7.203 + return rc; 7.204 +} 7.205 + 7.206 +int 7.207 +pdb_continue (struct task_struct *target) 7.208 +{ 7.209 + int rc = 0; 7.210 + unsigned long eflags; 7.211 + 7.212 + eflags = _pdb_get_register(target, LINUX_EFL); 7.213 + eflags &= ~X86_EFLAGS_TF; 7.214 + _pdb_set_register(target, LINUX_EFL, eflags); 7.215 + 7.216 + wake_up_process(target); 7.217 + 7.218 + return rc; 7.219 +} 7.220 + 7.221 int 7.222 -pdb_write_register (int pid, pdb_op_wr_reg_p op) 7.223 +pdb_step (struct task_struct *target) 7.224 +{ 7.225 + int rc = 0; 7.226 + unsigned long eflags; 7.227 + bwcpoint_p bkpt; 7.228 + 7.229 + eflags = _pdb_get_register(target, LINUX_EFL); 7.230 + eflags |= X86_EFLAGS_TF; 7.231 + _pdb_set_register(target, LINUX_EFL, eflags); 7.232 + 7.233 + bkpt = kmalloc(sizeof(bwcpoint_t), GFP_KERNEL); 7.234 + if ( bkpt == NULL ) 7.235 + { 7.236 + printk("error: unable to allocation memory\n"); 7.237 + return -1; 7.238 + } 7.239 + 7.240 + bkpt->process = target->pid; 7.241 + bkpt->address = 0; 7.242 + bkpt->type = BWC_DEBUG; 7.243 + 7.244 + list_add(&bkpt->list, &bwcpoint_list.list); 7.245 + 7.246 + wake_up_process(target); 7.247 + 7.248 + return rc; 7.249 +} 7.250 + 7.251 +int 7.252 +pdb_insert_memory_breakpoint (struct task_struct *target, 7.253 + memory_t address, u32 length) 7.254 +{ 7.255 + int rc = 0; 7.256 + bwcpoint_p bkpt; 7.257 + u8 breakpoint_opcode = 0xcc; 7.258 + 7.259 + printk("insert breakpoint %d:%lx len: %d\n", target->pid, address, length); 7.260 + 7.261 + bkpt = kmalloc(sizeof(bwcpoint_t), GFP_KERNEL); 7.262 + if ( bkpt == NULL ) 7.263 + { 7.264 + printk("error: unable to allocation memory\n"); 7.265 + return -1; 7.266 + } 7.267 + 7.268 + if ( length != 1 ) 7.269 + { 7.270 + printk("error: breakpoint length should be 1\n"); 7.271 + kfree(bkpt); 7.272 + return -1; 7.273 + } 7.274 + 7.275 + bkpt->process = target->pid; 7.276 + bkpt->address = address; 7.277 + bkpt->type = BWC_INT3; 7.278 + 7.279 + pdb_access_memory(target, address, &bkpt->old_value, 1, 0); 7.280 + pdb_access_memory(target, address, &breakpoint_opcode, 1, 1); 7.281 + 7.282 + list_add(&bkpt->list, &bwcpoint_list.list); 7.283 + 7.284 + printk("breakpoint_set %d:%lx OLD: 0x%x\n", 7.285 + target->pid, address, bkpt->old_value); 7.286 + 7.287 + return rc; 7.288 +} 7.289 + 7.290 +int 7.291 +pdb_remove_memory_breakpoint (struct task_struct *target, 7.292 + memory_t address, u32 length) 7.293 { 7.294 int rc = 0; 7.295 - struct task_struct *target; 7.296 - unsigned long offset; 7.297 - unsigned char *stack; 7.298 - unsigned long value = op->value; 7.299 + bwcpoint_p bkpt = NULL; 7.300 7.301 - /* 7.302 - printk ("pdb write register: 0x%x %2d 0x%lx\n", pid, op->reg, value); 7.303 - */ 7.304 + printk ("remove breakpoint %d:%lx\n", target->pid, address); 7.305 7.306 - read_lock(&tasklist_lock); 7.307 - target = find_task_by_pid(pid); 7.308 - if (target) 7.309 - get_task_struct(target); 7.310 - read_unlock(&tasklist_lock); 7.311 - 7.312 - switch (op->reg) 7.313 + struct list_head *entry; 7.314 + list_for_each(entry, &bwcpoint_list.list) 7.315 { 7.316 - case FS: 7.317 - target->thread.fs = value; 7.318 - return rc; 7.319 - case GS: 7.320 - target->thread.gs = value; 7.321 - return rc; 7.322 - case DS: 7.323 - case ES: 7.324 - value &= 0xffff; 7.325 - break; 7.326 - case SS: 7.327 - case CS: 7.328 - value &= 0xffff; 7.329 - break; 7.330 - case EFL: 7.331 - break; 7.332 + bkpt = list_entry(entry, bwcpoint_t, list); 7.333 + if ( target->pid == bkpt->process && 7.334 + address == bkpt->address && 7.335 + bkpt->type == BWC_INT3 ) 7.336 + break; 7.337 + } 7.338 + 7.339 + if (bkpt == &bwcpoint_list || bkpt == NULL) 7.340 + { 7.341 + printk ("error: no breakpoint found\n"); 7.342 + return -1; 7.343 } 7.344 7.345 - if (op->reg > GS) 7.346 - op->reg -= 2; 7.347 - offset = op->reg * sizeof(long); 7.348 - offset -= sizeof(struct pt_regs); 7.349 - stack = (unsigned char *)target->thread.esp0; 7.350 - stack += offset; 7.351 - *(unsigned long *) stack = op->value; 7.352 + list_del(&bkpt->list); 7.353 + 7.354 + pdb_access_memory(target, address, &bkpt->old_value, 1, 1); 7.355 + 7.356 + kfree(bkpt); 7.357 7.358 return rc; 7.359 } 7.360 7.361 + 7.362 +/***************************************************************/ 7.363 + 7.364 +int 7.365 +pdb_exceptions_notify (struct notifier_block *self, unsigned long val, 7.366 + void *data) 7.367 +{ 7.368 + struct die_args *args = (struct die_args *)data; 7.369 + 7.370 + switch (val) 7.371 + { 7.372 + case DIE_DEBUG: 7.373 + if (pdb_debug_fn(args->regs, args->trapnr, args->err)) 7.374 + return NOTIFY_STOP; 7.375 + break; 7.376 + case DIE_TRAP: 7.377 + if (args->trapnr == 3 && pdb_int3_fn(args->regs, args->err)) 7.378 + return NOTIFY_STOP; 7.379 + break; 7.380 + case DIE_INT3: /* without kprobes, we should never see DIE_INT3 */ 7.381 + case DIE_GPF: 7.382 + case DIE_PAGE_FAULT: 7.383 + default: 7.384 + break; 7.385 + } 7.386 + 7.387 + return NOTIFY_DONE; 7.388 +} 7.389 + 7.390 + 7.391 +int 7.392 +pdb_debug_fn (struct pt_regs *regs, long error_code, 7.393 + unsigned int condition) 7.394 +{ 7.395 + pdb_response_t resp; 7.396 + bwcpoint_p bkpt = NULL; 7.397 + 7.398 + struct list_head *entry; 7.399 + list_for_each(entry, &bwcpoint_list.list) 7.400 + { 7.401 + bkpt = list_entry(entry, bwcpoint_t, list); 7.402 + if ( current->pid == bkpt->process && 7.403 + bkpt->type == BWC_DEBUG ) 7.404 + break; 7.405 + } 7.406 + 7.407 + if (bkpt == &bwcpoint_list || bkpt == NULL) 7.408 + { 7.409 + printk("not my debug 0x%x 0x%lx\n", current->pid, regs->eip); 7.410 + return 0; 7.411 + } 7.412 + 7.413 + list_del(&bkpt->list); 7.414 + 7.415 + pdb_suspend(current); 7.416 + 7.417 + printk("(pdb) debug pid: %d, eip: 0x%08lx\n", current->pid, regs->eip); 7.418 + 7.419 + regs->eflags &= ~X86_EFLAGS_TF; 7.420 + set_tsk_thread_flag(current, TIF_SINGLESTEP); 7.421 + 7.422 + resp.operation = PDB_OPCODE_STEP; 7.423 + resp.process = current->pid; 7.424 + resp.status = PDB_RESPONSE_OKAY; 7.425 + 7.426 + pdb_send_response(&resp); 7.427 + 7.428 + return 1; 7.429 +} 7.430 + 7.431 + 7.432 +int 7.433 +pdb_int3_fn (struct pt_regs *regs, long error_code) 7.434 +{ 7.435 + pdb_response_t resp; 7.436 + bwcpoint_p bkpt = NULL; 7.437 + 7.438 + struct list_head *entry; 7.439 + list_for_each(entry, &bwcpoint_list.list) 7.440 + { 7.441 + bkpt = list_entry(entry, bwcpoint_t, list); 7.442 + if ( current->pid == bkpt->process && 7.443 + regs->eip == bkpt->address && 7.444 + bkpt->type == BWC_INT3 ) 7.445 + break; 7.446 + } 7.447 + 7.448 + if (bkpt == &bwcpoint_list || bkpt == NULL) 7.449 + { 7.450 + printk("not my int3 bkpt 0x%x 0x%lx\n", current->pid, regs->eip); 7.451 + return 0; 7.452 + } 7.453 + 7.454 + printk("(pdb) int3 pid: %d, eip: 0x%08lx\n", current->pid, regs->eip); 7.455 + 7.456 + pdb_suspend(current); 7.457 + 7.458 + resp.operation = PDB_OPCODE_CONTINUE; 7.459 + resp.process = current->pid; 7.460 + resp.status = PDB_RESPONSE_OKAY; 7.461 + 7.462 + pdb_send_response(&resp); 7.463 + 7.464 + return 1; 7.465 +} 7.466 + 7.467 /* 7.468 * Local variables: 7.469 * mode: C
8.1 --- a/tools/debugger/pdb/linux-2.6-module/module.c Thu Jul 28 12:34:45 2005 +0000 8.2 +++ b/tools/debugger/pdb/linux-2.6-module/module.c Thu Jul 28 21:28:23 2005 +0000 8.3 @@ -11,6 +11,8 @@ 8.4 #include <linux/module.h> 8.5 #include <linux/interrupt.h> 8.6 8.7 +#include <asm-i386/kdebug.h> 8.8 + 8.9 #include <asm-xen/evtchn.h> 8.10 #include <asm-xen/ctrl_if.h> 8.11 #include <asm-xen/hypervisor.h> 8.12 @@ -20,17 +22,23 @@ 8.13 #include <asm-xen/xen-public/io/ring.h> 8.14 8.15 #include "pdb_module.h" 8.16 +#include "pdb_debug.h" 8.17 8.18 #define PDB_RING_SIZE __RING_SIZE((pdb_sring_t *)0, PAGE_SIZE) 8.19 8.20 static pdb_back_ring_t pdb_ring; 8.21 static unsigned int pdb_evtchn; 8.22 static unsigned int pdb_irq; 8.23 +static unsigned int pdb_domain; 8.24 + 8.25 +/* work queue */ 8.26 +static void pdb_work_handler(void *unused); 8.27 +static DECLARE_WORK(pdb_deferred_work, pdb_work_handler, NULL); 8.28 8.29 /* 8.30 * send response to a pdb request 8.31 */ 8.32 -static void 8.33 +void 8.34 pdb_send_response (pdb_response_t *response) 8.35 { 8.36 pdb_response_t *resp; 8.37 @@ -38,6 +46,7 @@ pdb_send_response (pdb_response_t *respo 8.38 resp = RING_GET_RESPONSE(&pdb_ring, pdb_ring.rsp_prod_pvt); 8.39 8.40 memcpy(resp, response, sizeof(pdb_response_t)); 8.41 + resp->domain = pdb_domain; 8.42 8.43 wmb(); /* Ensure other side can see the response fields. */ 8.44 pdb_ring.rsp_prod_pvt++; 8.45 @@ -53,43 +62,98 @@ static void 8.46 pdb_process_request (pdb_request_t *request) 8.47 { 8.48 pdb_response_t resp; 8.49 + struct task_struct *target; 8.50 + 8.51 + read_lock(&tasklist_lock); 8.52 + target = find_task_by_pid(request->process); 8.53 + if (target) 8.54 + get_task_struct(target); 8.55 + read_unlock(&tasklist_lock); 8.56 8.57 resp.operation = request->operation; 8.58 - resp.domain = request->domain; 8.59 resp.process = request->process; 8.60 8.61 + if (!target) 8.62 + { 8.63 + printk ("(linux) target not found 0x%x\n", request->process); 8.64 + resp.status = PDB_RESPONSE_ERROR; 8.65 + goto response; 8.66 + } 8.67 + 8.68 switch (request->operation) 8.69 { 8.70 + case PDB_OPCODE_PAUSE : 8.71 + pdb_suspend(target); 8.72 + resp.status = PDB_RESPONSE_OKAY; 8.73 + break; 8.74 case PDB_OPCODE_ATTACH : 8.75 - pdb_attach(request->process); 8.76 + pdb_suspend(target); 8.77 + pdb_domain = request->u.attach.domain; 8.78 + printk("(linux) attach dom:0x%x pid:0x%x\n", 8.79 + pdb_domain, request->process); 8.80 resp.status = PDB_RESPONSE_OKAY; 8.81 break; 8.82 case PDB_OPCODE_DETACH : 8.83 - pdb_detach(request->process); 8.84 + pdb_resume(target); 8.85 + printk("(linux) detach 0x%x\n", request->process); 8.86 resp.status = PDB_RESPONSE_OKAY; 8.87 break; 8.88 case PDB_OPCODE_RD_REGS : 8.89 - pdb_read_register(request->process, &resp.u.rd_regs); 8.90 + pdb_read_registers(target, &resp.u.rd_regs); 8.91 resp.status = PDB_RESPONSE_OKAY; 8.92 break; 8.93 case PDB_OPCODE_WR_REG : 8.94 - pdb_write_register(request->process, &request->u.wr_reg); 8.95 + pdb_write_register(target, &request->u.wr_reg); 8.96 + resp.status = PDB_RESPONSE_OKAY; 8.97 + break; 8.98 + case PDB_OPCODE_RD_MEM : 8.99 + pdb_access_memory(target, request->u.rd_mem.address, 8.100 + &resp.u.rd_mem.data, request->u.rd_mem.length, 0); 8.101 + resp.u.rd_mem.address = request->u.rd_mem.address; 8.102 + resp.u.rd_mem.length = request->u.rd_mem.length; 8.103 + resp.status = PDB_RESPONSE_OKAY; 8.104 + break; 8.105 + case PDB_OPCODE_WR_MEM : 8.106 + pdb_access_memory(target, request->u.wr_mem.address, 8.107 + &request->u.wr_mem.data, request->u.wr_mem.length, 1); 8.108 + resp.status = PDB_RESPONSE_OKAY; 8.109 + break; 8.110 + case PDB_OPCODE_CONTINUE : 8.111 + pdb_continue(target); 8.112 + goto no_response; 8.113 + break; 8.114 + case PDB_OPCODE_STEP : 8.115 + pdb_step(target); 8.116 + resp.status = PDB_RESPONSE_OKAY; 8.117 + goto no_response; 8.118 + break; 8.119 + case PDB_OPCODE_SET_BKPT : 8.120 + pdb_insert_memory_breakpoint(target, request->u.bkpt.address, 8.121 + request->u.bkpt.length); 8.122 + resp.status = PDB_RESPONSE_OKAY; 8.123 + break; 8.124 + case PDB_OPCODE_CLR_BKPT : 8.125 + pdb_remove_memory_breakpoint(target, request->u.bkpt.address, 8.126 + request->u.bkpt.length); 8.127 resp.status = PDB_RESPONSE_OKAY; 8.128 break; 8.129 default: 8.130 printk("(pdb) unknown request operation %d\n", request->operation); 8.131 resp.status = PDB_RESPONSE_ERROR; 8.132 } 8.133 - 8.134 + 8.135 + response: 8.136 pdb_send_response (&resp); 8.137 + 8.138 + no_response: 8.139 return; 8.140 } 8.141 8.142 /* 8.143 - * receive a pdb request 8.144 + * work queue 8.145 */ 8.146 -static irqreturn_t 8.147 -pdb_interrupt (int irq, void *dev_id, struct pt_regs *ptregs) 8.148 +static void 8.149 +pdb_work_handler (void *unused) 8.150 { 8.151 pdb_request_t *req; 8.152 RING_IDX i, rp; 8.153 @@ -106,11 +170,19 @@ pdb_interrupt (int irq, void *dev_id, st 8.154 8.155 } 8.156 pdb_ring.req_cons = i; 8.157 +} 8.158 + 8.159 +/* 8.160 + * receive a pdb request 8.161 + */ 8.162 +static irqreturn_t 8.163 +pdb_interrupt (int irq, void *dev_id, struct pt_regs *ptregs) 8.164 +{ 8.165 + schedule_work(&pdb_deferred_work); 8.166 8.167 return IRQ_HANDLED; 8.168 } 8.169 8.170 - 8.171 static void 8.172 pdb_send_connection_status(int status, memory_t ring) 8.173 { 8.174 @@ -136,8 +208,6 @@ pdb_send_connection_status(int status, m 8.175 static void 8.176 pdb_ctrlif_rx(ctrl_msg_t *msg, unsigned long id) 8.177 { 8.178 -printk ("pdb ctrlif rx\n"); 8.179 - 8.180 switch (msg->subtype) 8.181 { 8.182 case CMSG_DEBUG_CONNECTION_STATUS: 8.183 @@ -161,18 +231,35 @@ printk ("pdb ctrlif rx\n"); 8.184 return; 8.185 } 8.186 8.187 + 8.188 +/********************************************************************/ 8.189 + 8.190 +static struct notifier_block pdb_exceptions_nb = 8.191 +{ 8.192 + .notifier_call = pdb_exceptions_notify, 8.193 + .priority = 0x1 /* low priority */ 8.194 +}; 8.195 + 8.196 + 8.197 static int __init 8.198 -pdb_initialize(void) 8.199 +pdb_initialize (void) 8.200 { 8.201 + int err; 8.202 pdb_sring_t *sring; 8.203 8.204 printk("----\npdb initialize %s %s\n", __DATE__, __TIME__); 8.205 8.206 + pdb_initialize_bwcpoint(); 8.207 + 8.208 /* 8.209 if ( xen_start_info.flags & SIF_INITDOMAIN ) 8.210 return 1; 8.211 */ 8.212 8.213 + pdb_evtchn = 0; 8.214 + pdb_irq = 0; 8.215 + pdb_domain = 0; 8.216 + 8.217 (void)ctrl_if_register_receiver(CMSG_DEBUG, pdb_ctrlif_rx, 8.218 CALLBACK_IN_BLOCKING_CONTEXT); 8.219 8.220 @@ -185,12 +272,21 @@ pdb_initialize(void) 8.221 pdb_send_connection_status(PDB_CONNECTION_STATUS_UP, 8.222 virt_to_machine(pdb_ring.sring) >> PAGE_SHIFT); 8.223 8.224 - return 0; 8.225 + /* handler for int1 & int3 */ 8.226 + err = register_die_notifier(&pdb_exceptions_nb); 8.227 + 8.228 + return err; 8.229 } 8.230 8.231 +extern struct notifier_block *i386die_chain; 8.232 +extern spinlock_t die_notifier_lock; 8.233 + 8.234 static void __exit 8.235 pdb_terminate(void) 8.236 { 8.237 + int err = 0; 8.238 + unsigned long flags; 8.239 + 8.240 printk("pdb cleanup\n"); 8.241 8.242 (void)ctrl_if_unregister_receiver(CMSG_DEBUG, pdb_ctrlif_rx); 8.243 @@ -208,6 +304,12 @@ pdb_terminate(void) 8.244 } 8.245 8.246 pdb_send_connection_status(PDB_CONNECTION_STATUS_DOWN, 0); 8.247 + 8.248 + spin_lock_irqsave(&die_notifier_lock, flags); 8.249 + err = notifier_chain_unregister(&i386die_chain, &pdb_exceptions_nb); 8.250 + spin_unlock_irqrestore(&die_notifier_lock, flags); 8.251 + 8.252 + return; 8.253 } 8.254 8.255
9.1 --- a/tools/debugger/pdb/linux-2.6-module/pdb_module.h Thu Jul 28 12:34:45 2005 +0000 9.2 +++ b/tools/debugger/pdb/linux-2.6-module/pdb_module.h Thu Jul 28 21:28:23 2005 +0000 9.3 @@ -1,35 +1,80 @@ 9.4 9.5 -#ifndef __XEN_PDB_H_ 9.6 -#define __XEN_PDB_H_ 9.7 +#ifndef __PDB_MODULE_H_ 9.8 +#define __PDB_MODULE_H_ 9.9 9.10 #include "../pdb_caml_xen.h" 9.11 9.12 -#define PDB_OPCODE_ATTACH 1 9.13 -#define PDB_OPCODE_DETACH 2 9.14 +#define PDB_OPCODE_PAUSE 1 9.15 9.16 -#define PDB_OPCODE_RD_REGS 3 9.17 +#define PDB_OPCODE_ATTACH 2 9.18 +typedef struct pdb_op_attach 9.19 +{ 9.20 + u32 domain; 9.21 +} pdb_op_attach_t, *pdb_op_attach_p; 9.22 + 9.23 +#define PDB_OPCODE_DETACH 3 9.24 + 9.25 +#define PDB_OPCODE_RD_REGS 4 9.26 typedef struct pdb_op_rd_regs 9.27 { 9.28 u32 reg[GDB_REGISTER_FRAME_SIZE]; 9.29 } pdb_op_rd_regs_t, *pdb_op_rd_regs_p; 9.30 9.31 -#define PDB_OPCODE_WR_REG 4 9.32 +#define PDB_OPCODE_WR_REG 5 9.33 typedef struct pdb_op_wr_reg 9.34 { 9.35 u32 reg; 9.36 u32 value; 9.37 } pdb_op_wr_reg_t, *pdb_op_wr_reg_p; 9.38 9.39 +#define PDB_OPCODE_RD_MEM 6 9.40 +typedef struct pdb_op_rd_mem_req 9.41 +{ 9.42 + u32 address; 9.43 + u32 length; 9.44 +} pdb_op_rd_mem_req_t, *pdb_op_rd_mem_req_p; 9.45 + 9.46 +typedef struct pdb_op_rd_mem_resp 9.47 +{ 9.48 + u32 address; 9.49 + u32 length; 9.50 + u8 data[1024]; 9.51 +} pdb_op_rd_mem_resp_t, *pdb_op_rd_mem_resp_p; 9.52 + 9.53 +#define PDB_OPCODE_WR_MEM 7 9.54 +typedef struct pdb_op_wr_mem 9.55 +{ 9.56 + u32 address; 9.57 + u32 length; 9.58 + u8 data[1024]; /* arbitrary */ 9.59 +} pdb_op_wr_mem_t, *pdb_op_wr_mem_p; 9.60 + 9.61 +#define PDB_OPCODE_CONTINUE 8 9.62 +#define PDB_OPCODE_STEP 9 9.63 + 9.64 +#define PDB_OPCODE_SET_BKPT 10 9.65 +#define PDB_OPCODE_CLR_BKPT 11 9.66 +typedef struct pdb_op_bkpt 9.67 +{ 9.68 + u32 address; 9.69 + u32 length; 9.70 +} pdb_op_bkpt_t, *pdb_op_bkpt_p; 9.71 + 9.72 + 9.73 typedef struct 9.74 { 9.75 u8 operation; /* PDB_OPCODE_??? */ 9.76 - u32 domain; 9.77 u32 process; 9.78 union 9.79 { 9.80 - pdb_op_wr_reg_t wr_reg; 9.81 + pdb_op_attach_t attach; 9.82 + pdb_op_wr_reg_t wr_reg; 9.83 + pdb_op_rd_mem_req_t rd_mem; 9.84 + pdb_op_wr_mem_t wr_mem; 9.85 + pdb_op_bkpt_t bkpt; 9.86 } u; 9.87 } pdb_request_t, *pdb_request_p; 9.88 + 9.89 9.90 9.91 #define PDB_RESPONSE_OKAY 0 9.92 @@ -42,20 +87,14 @@ typedef struct { 9.93 s16 status; /* PDB_RESPONSE_??? */ 9.94 union 9.95 { 9.96 - pdb_op_rd_regs_t rd_regs; 9.97 + pdb_op_rd_regs_t rd_regs; 9.98 + pdb_op_rd_mem_resp_t rd_mem; 9.99 } u; 9.100 } pdb_response_t, *pdb_response_p; 9.101 9.102 9.103 DEFINE_RING_TYPES(pdb, pdb_request_t, pdb_response_t); 9.104 9.105 - 9.106 -int pdb_attach (int pid); 9.107 -int pdb_detach (int pid); 9.108 -int pdb_read_register (int pid, pdb_op_rd_regs_p op); 9.109 -int pdb_write_register (int pid, pdb_op_wr_reg_p op); 9.110 - 9.111 - 9.112 #endif 9.113 9.114
10.1 --- a/tools/debugger/pdb/pdb_caml_process.c Thu Jul 28 12:34:45 2005 +0000 10.2 +++ b/tools/debugger/pdb/pdb_caml_process.c Thu Jul 28 21:28:23 2005 +0000 10.3 @@ -96,17 +96,19 @@ process_handle_response (value ring) 10.4 memset(msg, 0, sizeof(msg)); 10.5 10.6 rp = my_ring->sring->rsp_prod; 10.7 - rmb(); /* Ensure we see queued responses up to 'rp'. */ 10.8 + rmb(); /* Ensure we see queued responses up to 'rp'. */ 10.9 10.10 + /* default response is OK unless the command has something 10.11 + more interesting to say */ 10.12 sprintf(msg, "OK"); 10.13 10.14 - /* for ( loop = my_ring->rsp_cons; loop != rp; loop++ ) */ 10.15 if (my_ring->rsp_cons != rp) 10.16 { 10.17 resp = RING_GET_RESPONSE(my_ring, my_ring->rsp_cons); 10.18 10.19 switch (resp->operation) 10.20 { 10.21 + case PDB_OPCODE_PAUSE : 10.22 case PDB_OPCODE_ATTACH : 10.23 case PDB_OPCODE_DETACH : 10.24 break; 10.25 @@ -123,21 +125,57 @@ process_handle_response (value ring) 10.26 10.27 break; 10.28 } 10.29 - 10.30 case PDB_OPCODE_WR_REG : 10.31 { 10.32 - printf("(linux) wr regs\n"); 10.33 + /* should check the return status */ 10.34 + break; 10.35 + } 10.36 + 10.37 + case PDB_OPCODE_RD_MEM : 10.38 + { 10.39 + int loop; 10.40 + pdb_op_rd_mem_resp_p mem = &resp->u.rd_mem; 10.41 + 10.42 + for (loop = 0; loop < mem->length; loop ++) 10.43 + { 10.44 + sprintf(&msg[loop * 2], "%02x", mem->data[loop]); 10.45 + } 10.46 + break; 10.47 + } 10.48 + case PDB_OPCODE_WR_MEM : 10.49 + { 10.50 /* should check the return status */ 10.51 break; 10.52 } 10.53 + 10.54 + /* this is equivalent to process_xen_virq */ 10.55 + case PDB_OPCODE_CONTINUE : 10.56 + { 10.57 + sprintf(msg, "S05"); 10.58 + break; 10.59 + } 10.60 + case PDB_OPCODE_STEP : 10.61 + { 10.62 + sprintf(msg, "S05"); 10.63 + break; 10.64 + } 10.65 + 10.66 + case PDB_OPCODE_SET_BKPT : 10.67 + { 10.68 + break; 10.69 + } 10.70 + case PDB_OPCODE_CLR_BKPT : 10.71 + { 10.72 + break; 10.73 + } 10.74 + 10.75 default : 10.76 - printf("(process) UNKNOWN MESSAGE TYPE IN RESPONSE\n"); 10.77 + printf("(linux) UNKNOWN MESSAGE TYPE IN RESPONSE\n"); 10.78 break; 10.79 } 10.80 10.81 my_ring->rsp_cons++; 10.82 } 10.83 - /* my_ring->rsp_cons = loop; */ 10.84 10.85 msglen = strlen(msg); 10.86 result = caml_alloc(3,0); 10.87 @@ -164,7 +202,7 @@ proc_attach_debugger (value context) 10.88 decode_context(&ctx, context); 10.89 10.90 req.operation = PDB_OPCODE_ATTACH; 10.91 - req.domain = ctx.domain; 10.92 + req.u.attach.domain = ctx.domain; 10.93 req.process = ctx.process; 10.94 10.95 send_request (ctx.ring, ctx.evtchn, &req); 10.96 @@ -190,7 +228,6 @@ proc_detach_debugger (value context) 10.97 fflush(stdout); 10.98 10.99 req.operation = PDB_OPCODE_DETACH; 10.100 - req.domain = ctx.domain; 10.101 req.process = ctx.process; 10.102 10.103 send_request (ctx.ring, ctx.evtchn, &req); 10.104 @@ -207,12 +244,18 @@ proc_pause_target (value context) 10.105 { 10.106 CAMLparam1(context); 10.107 context_t ctx; 10.108 + pdb_request_t req; 10.109 10.110 decode_context(&ctx, context); 10.111 10.112 printf("(pdb) pause target %d %d\n", ctx.domain, ctx.process); 10.113 fflush(stdout); 10.114 10.115 + req.operation = PDB_OPCODE_PAUSE; 10.116 + req.process = ctx.process; 10.117 + 10.118 + send_request (ctx.ring, ctx.evtchn, &req); 10.119 + 10.120 CAMLreturn(Val_unit); 10.121 } 10.122 10.123 @@ -231,7 +274,6 @@ proc_read_registers (value context) 10.124 decode_context(&ctx, context); 10.125 10.126 req.operation = PDB_OPCODE_RD_REGS; 10.127 - req.domain = ctx.domain; 10.128 req.process = ctx.process; 10.129 10.130 send_request (ctx.ring, ctx.evtchn, &req); 10.131 @@ -257,7 +299,6 @@ proc_write_register (value context, valu 10.132 decode_context(&ctx, context); 10.133 10.134 req.operation = PDB_OPCODE_WR_REG; 10.135 - req.domain = ctx.domain; 10.136 req.process = ctx.process; 10.137 req.u.wr_reg.value = my_newval; 10.138 10.139 @@ -291,64 +332,28 @@ proc_write_register (value context, valu 10.140 10.141 10.142 /* 10.143 - * proc_read_memory : context_t -> int32 -> int -> int 10.144 + * proc_read_memory : context_t -> int32 -> int -> unit 10.145 */ 10.146 value 10.147 proc_read_memory (value context, value address, value length) 10.148 { 10.149 CAMLparam3(context, address, length); 10.150 - CAMLlocal2(result, temp); 10.151 10.152 context_t ctx; 10.153 - int loop; 10.154 - char *buffer; 10.155 - /* memory_t my_address = Int32_val(address); */ 10.156 - u32 my_length = Int_val(length); 10.157 - 10.158 - printf ("(pdb) read memory\n"); 10.159 + pdb_request_t req; 10.160 10.161 decode_context(&ctx, context); 10.162 10.163 - buffer = malloc(my_length); 10.164 - if ( buffer == NULL ) 10.165 - { 10.166 - printf("(pdb) read memory: malloc failed.\n"); fflush(stdout); 10.167 - failwith("read memory error"); 10.168 - } 10.169 - 10.170 - /* 10.171 - if ( xendebug_read_memory(xc_handle, ctx.domain, ctx.vcpu, 10.172 - my_address, my_length, buffer) ) 10.173 - { 10.174 - printf("(pdb) read memory error!\n"); fflush(stdout); 10.175 - failwith("read memory error"); 10.176 - } 10.177 - */ 10.178 - 10.179 - memset(buffer, 0xff, my_length); 10.180 + req.operation = PDB_OPCODE_RD_MEM; 10.181 + req.process = ctx.process; 10.182 + req.u.rd_mem.address = Int32_val(address); 10.183 + req.u.rd_mem.length = Int_val(length); 10.184 10.185 - result = caml_alloc(2,0); 10.186 - if ( my_length > 0 ) /* car */ 10.187 - { 10.188 - Store_field(result, 0, Val_int(buffer[my_length - 1] & 0xff)); 10.189 - } 10.190 - else 10.191 + send_request(ctx.ring, ctx.evtchn, &req); 10.192 + 10.193 + CAMLreturn(Val_unit); 10.194 +} 10.195 10.196 - { 10.197 - Store_field(result, 0, Val_int(0)); 10.198 - } 10.199 - Store_field(result, 1, Val_int(0)); /* cdr */ 10.200 - 10.201 - for (loop = 1; loop < my_length; loop++) 10.202 - { 10.203 - temp = result; 10.204 - result = caml_alloc(2,0); 10.205 - Store_field(result, 0, Val_int(buffer[my_length - loop - 1] & 0xff)); 10.206 - Store_field(result, 1, temp); 10.207 - } 10.208 - 10.209 - CAMLreturn(result); 10.210 -} 10.211 10.212 /* 10.213 * proc_write_memory : context_t -> int32 -> int list -> unit 10.214 @@ -360,52 +365,39 @@ proc_write_memory (value context, value 10.215 CAMLlocal1(node); 10.216 10.217 context_t ctx; 10.218 - 10.219 - char buffer[4096]; /* a big buffer */ 10.220 - memory_t my_address; 10.221 + pdb_request_t req; 10.222 u32 length = 0; 10.223 10.224 - printf ("(pdb) write memory\n"); 10.225 + decode_context(&ctx, context); 10.226 10.227 - decode_context(&ctx, context); 10.228 + req.operation = PDB_OPCODE_WR_MEM; 10.229 + req.process = ctx.process; 10.230 10.231 node = val_list; 10.232 if ( Int_val(node) == 0 ) /* gdb functionalty test uses empty list */ 10.233 { 10.234 - CAMLreturn(Val_unit); 10.235 - } 10.236 - 10.237 - while ( Int_val(Field(node,1)) != 0 ) 10.238 - { 10.239 - buffer[length++] = Int_val(Field(node, 0)); 10.240 - node = Field(node,1); 10.241 + req.u.wr_mem.address = Int32_val(address); 10.242 + req.u.wr_mem.length = 0; 10.243 } 10.244 - buffer[length++] = Int_val(Field(node, 0)); 10.245 - 10.246 - my_address = (memory_t) Int32_val(address); 10.247 - 10.248 - /* 10.249 - if ( xendebug_write_memory(xc_handle, ctx.domain, ctx.vcpu, 10.250 - my_address, length, buffer) ) 10.251 + else 10.252 { 10.253 - printf("(pdb) write memory error!\n"); fflush(stdout); 10.254 - failwith("write memory error"); 10.255 + while ( Int_val(Field(node,1)) != 0 ) 10.256 + { 10.257 + req.u.wr_mem.data[length++] = Int_val(Field(node, 0)); 10.258 + node = Field(node,1); 10.259 + } 10.260 + req.u.wr_mem.data[length++] = Int_val(Field(node, 0)); 10.261 + 10.262 + req.u.wr_mem.address = Int32_val(address); 10.263 + req.u.wr_mem.length = length; 10.264 } 10.265 - */ 10.266 - { 10.267 - int loop; 10.268 - for (loop = 0; loop < length; loop++) 10.269 - { 10.270 - printf (" %02x", buffer[loop]); 10.271 - } 10.272 - printf ("\n"); 10.273 - } 10.274 - 10.275 + 10.276 + send_request(ctx.ring, ctx.evtchn, &req); 10.277 + 10.278 CAMLreturn(Val_unit); 10.279 } 10.280 10.281 10.282 - 10.283 /* 10.284 * proc_continue_target : context_t -> unit 10.285 */ 10.286 @@ -415,17 +407,14 @@ proc_continue_target (value context) 10.287 CAMLparam1(context); 10.288 10.289 context_t ctx; 10.290 + pdb_request_t req; 10.291 10.292 decode_context(&ctx, context); 10.293 10.294 - /* 10.295 - if ( xendebug_continue(xc_handle, ctx.domain, ctx.vcpu) ) 10.296 - { 10.297 - printf("(pdb) continue\n"); fflush(stdout); 10.298 - failwith("continue"); 10.299 - } 10.300 - */ 10.301 - printf ("CONTINUE\n"); 10.302 + req.operation = PDB_OPCODE_CONTINUE; 10.303 + req.process = ctx.process; 10.304 + 10.305 + send_request(ctx.ring, ctx.evtchn, &req); 10.306 10.307 CAMLreturn(Val_unit); 10.308 } 10.309 @@ -439,17 +428,14 @@ proc_step_target (value context) 10.310 CAMLparam1(context); 10.311 10.312 context_t ctx; 10.313 + pdb_request_t req; 10.314 10.315 decode_context(&ctx, context); 10.316 10.317 - /* 10.318 - if ( xendebug_step(xc_handle, ctx.domain, ctx.vcpu) ) 10.319 - { 10.320 - printf("(pdb) step\n"); fflush(stdout); 10.321 - failwith("step"); 10.322 - } 10.323 - */ 10.324 - printf ("STEP\n"); 10.325 + req.operation = PDB_OPCODE_STEP; 10.326 + req.process = ctx.process; 10.327 + 10.328 + send_request(ctx.ring, ctx.evtchn, &req); 10.329 10.330 CAMLreturn(Val_unit); 10.331 } 10.332 @@ -465,22 +451,16 @@ proc_insert_memory_breakpoint (value con 10.333 CAMLparam3(context, address, length); 10.334 10.335 context_t ctx; 10.336 - memory_t my_address = (memory_t) Int32_val(address); 10.337 - int my_length = Int_val(length); 10.338 + pdb_request_t req; 10.339 10.340 decode_context(&ctx, context); 10.341 10.342 - printf ("(pdb) insert memory breakpoint 0x%lx %d\n", 10.343 - my_address, my_length); 10.344 + req.operation = PDB_OPCODE_SET_BKPT; 10.345 + req.process = ctx.process; 10.346 + req.u.bkpt.address = (memory_t) Int32_val(address); 10.347 + req.u.bkpt.length = Int_val(length); 10.348 10.349 - /* 10.350 - if ( xendebug_insert_memory_breakpoint(xc_handle, ctx.domain, ctx.vcpu, 10.351 - my_address, my_length) ) 10.352 - { 10.353 - printf("(pdb) error: insert memory breakpoint\n"); fflush(stdout); 10.354 - failwith("insert memory breakpoint"); 10.355 - } 10.356 - */ 10.357 + send_request(ctx.ring, ctx.evtchn, &req); 10.358 10.359 CAMLreturn(Val_unit); 10.360 } 10.361 @@ -494,24 +474,16 @@ proc_remove_memory_breakpoint (value con 10.362 CAMLparam3(context, address, length); 10.363 10.364 context_t ctx; 10.365 - 10.366 - memory_t my_address = (memory_t) Int32_val(address); 10.367 - int my_length = Int_val(length); 10.368 - 10.369 - printf ("(pdb) remove memory breakpoint 0x%lx %d\n", 10.370 - my_address, my_length); 10.371 + pdb_request_t req; 10.372 10.373 decode_context(&ctx, context); 10.374 10.375 - /* 10.376 - if ( xendebug_remove_memory_breakpoint(xc_handle, 10.377 - ctx.domain, ctx.vcpu, 10.378 - my_address, my_length) ) 10.379 - { 10.380 - printf("(pdb) error: remove memory breakpoint\n"); fflush(stdout); 10.381 - failwith("remove memory breakpoint"); 10.382 - } 10.383 - */ 10.384 + req.operation = PDB_OPCODE_CLR_BKPT; 10.385 + req.process = ctx.process; 10.386 + req.u.bkpt.address = (memory_t) Int32_val(address); 10.387 + req.u.bkpt.length = Int_val(length); 10.388 + 10.389 + send_request(ctx.ring, ctx.evtchn, &req); 10.390 10.391 CAMLreturn(Val_unit); 10.392 }
11.1 --- a/tools/debugger/pdb/pdb_caml_xcs.c Thu Jul 28 12:34:45 2005 +0000 11.2 +++ b/tools/debugger/pdb/pdb_caml_xcs.c Thu Jul 28 21:28:23 2005 +0000 11.3 @@ -201,7 +201,7 @@ xcs_connect (value path, value msg_type) 11.4 ret = connect(control_fd, (struct sockaddr *)&addr, len); 11.5 if (ret < 0) 11.6 { 11.7 - printf("error connecting to xcs(ctrl)! (%d)\n", errno); 11.8 + printf("error connecting to xcs (ctrl)! (%d)\n", errno); 11.9 goto ctrl_fd_fail; 11.10 } 11.11 11.12 @@ -235,7 +235,7 @@ xcs_connect (value path, value msg_type) 11.13 ret = connect(data_fd, (struct sockaddr *)&addr, len); 11.14 if (ret < 0) 11.15 { 11.16 - printf("error connecting to xcs(data)! (%d)\n", errno); 11.17 + printf("error connecting to xcs (data)! (%d)\n", errno); 11.18 goto data_fd_fail; 11.19 } 11.20
12.1 --- a/tools/debugger/pdb/readme Thu Jul 28 12:34:45 2005 +0000 12.2 +++ b/tools/debugger/pdb/readme Thu Jul 28 21:28:23 2005 +0000 12.3 @@ -31,7 +31,7 @@ Installation 12.4 Build the target domains with debugging symbols. 12.5 make CONFIG_DEBUG_INFO=true CONFIG_FRAME_POINTER=false linux-2.6-xenU-build 12.6 12.7 - You can also change linux-2.6.11-xenU/Makefile 12.8 + You can also change linux-2.6.12-xenU/Makefile 12.9 CONFIG_CC_OPTIMIZE_FOR_SIZE from -O2 to -O 12.10 12.11 - Build PDB 12.12 @@ -46,7 +46,7 @@ Usage 12.13 domain-0.xeno# ./pdb <port> 12.14 12.15 - Run GDB 12.16 - hostname% gdb <xeno.bk>/dist/install/boot/vmlinux-syms-2.6.11.11-xenU 12.17 + hostname% gdb <xeno.bk>/dist/install/boot/vmlinux-syms-2.6.12-xenU 12.18 12.19 (gdb) target remote domain-0.xeno:<port> 12.20 12.21 @@ -76,9 +76,18 @@ Usage 12.22 continue 12.23 print 12.24 12.25 +Process 12.26 + 12.27 + PDB can also debug a process running in a Linux 2.6 domain. 12.28 + After running PDB in domain 0, insert the pdb module in dom u: 12.29 + 12.30 + % insmod linux-2.6-module/pdb.ko 12.31 + 12.32 + Load GDB with the appropriate symbols, and attach with 12.33 + 12.34 + (gdb) maint packet x context = process <domid> <pid> 12.35 12.36 To Do 12.37 12.38 - watchpoints 12.39 - support for SMP 12.40 -- support for user applications