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