This is the mail archive of the gdb@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Remote set thread breakpoint


>>I'm thinking about extending the remote protocol for thread breakpoints.
>>The easiest solution would be to just add another data field to the Z
>>commands, like:
>>Ztype,addr,length,threadid
>>If threadid is given, gdbserver can use it. If it's -1 or not present (as in
>>the present implementation) it's a global breakpoint.
>>But if this would cause incompatibilities with existing parsers it may
>>be better to create a new command, even if it's just Z5 and the rest
>>is the same.
>>What would be better? Or is something like that already in the pipe?
>
>Yes [zZ]5 would be safer.  Would also be a good oportunity to formalize how to probe support for this packet - Z5?  Given things like vCont and its vCont? query, a [better?] alternative might be be vBP...
>
>Just note that there is a small challenge here.  GDB internally assumes that breakpoints are global (it's a limitation / bug) - you'll need to also investigate  what needs to be changed closer to GDB's core.

I have a first shot and wanted to get some opinions. I'm not asking that
this patch gets included into gdb. It's more about knowing if I'm on the
right track, if I have missed some stuff, what difficulties these changes
may provide etc.
The core handling is quite untouched (so still global BPs), only the remote
target is implemented as I don't know other targets at all. The fallback
is anyway to use the normal BP routines if thread BP is not available.
I also didn't add a new command probe for Z5, I just used the same
as is already there for the other Z commands.

This is against gdb-6.1.1, I couldn't get 6.2 to compile (didn't try cvs).
I can still change it for cvs-gdb when it has a future :)

Thanks 

bye  Fabi


diff -ru gdb-6.1.1o/gdb/breakpoint.c gdb-6.1.1/gdb/breakpoint.c
--- gdb-6.1.1o/gdb/breakpoint.c 2004-06-12 19:58:23.000000000 +0200
+++ gdb-6.1.1/gdb/breakpoint.c  2004-09-10 16:04:58.687500000 +0200
@@ -781,8 +781,14 @@
            val = target_insert_hw_breakpoint (bpt->address, 
                                               bpt->shadow_contents);
          else
-           val = target_insert_breakpoint (bpt->address,
-                                           bpt->shadow_contents);
+           if (-1!=bpt->owner->thread) {
+             val = target_insert_thread_breakpoint (bpt->address,
+                 bpt->shadow_contents,
+                 ptid_get_pid (thread_id_to_pid (bpt->owner->thread)));
+           } else {
+             val = target_insert_breakpoint (bpt->address,
+                 bpt->shadow_contents);
+           }
        }
       else
        {
@@ -801,7 +807,15 @@
                  CORE_ADDR addr = overlay_unmapped_address (bpt->address,
                                                             bpt->section);
                  /* Set a software (trap) breakpoint at the LMA.  */
-                 val = target_insert_breakpoint (addr, bpt->shadow_contents);
+                 if (-1!=bpt->owner->thread) {
+                   val = target_insert_thread_breakpoint (addr,
+                   bpt->shadow_contents,
+                   ptid_get_pid (thread_id_to_pid (bpt->owner->thread)));
+                 } else {
+                   val = target_insert_breakpoint (addr,
+                   bpt->shadow_contents);
+                 }
+
                  if (val != 0)
                    fprintf_unfiltered (tmp_error_stream, 
                                        "Overlay breakpoint %d failed: in ROM?", 
@@ -816,8 +830,14 @@
                val = target_insert_hw_breakpoint (bpt->address, 
                                                   bpt->shadow_contents);
              else
-               val = target_insert_breakpoint (bpt->address,
-                                               bpt->shadow_contents);
+               if (-1!=bpt->owner->thread) {
+                   val = target_insert_thread_breakpoint (bpt->address,
+                       bpt->shadow_contents,
+                       ptid_get_pid (thread_id_to_pid (bpt->owner->thread)));
+               } else {
+                   val = target_insert_breakpoint (bpt->address,
+                       bpt->shadow_contents);
+               }
            }
          else
            {
@@ -1015,7 +1035,15 @@
       /* If we get here, we must have a callback mechanism for exception
         events -- with g++ style embedded label support, we insert
         ordinary breakpoints and not catchpoints. */
-      val = target_insert_breakpoint (bpt->address, bpt->shadow_contents);
+      if (-1!=bpt->owner->thread) {
+       val = target_insert_thread_breakpoint (bpt->address,
+           bpt->shadow_contents,
+           ptid_get_pid (thread_id_to_pid (bpt->owner->thread)));
+      } else {
+       val = target_insert_breakpoint (bpt->address,
+           bpt->shadow_contents);
+      }
+
       if (val)
        {
          /* Couldn't set breakpoint for some reason */
@@ -1208,7 +1236,14 @@
        if (b->loc_type == bp_loc_hardware_breakpoint)
          val = target_insert_hw_breakpoint (b->address, b->shadow_contents);
        else
-         val = target_insert_breakpoint (b->address, b->shadow_contents);
+         if (-1!=b->owner->thread) {
+           val = target_insert_thread_breakpoint (b->address,
+               b->shadow_contents,
+               ptid_get_pid (thread_id_to_pid (b->owner->thread)));
+         } else {
+           val = target_insert_breakpoint (b->address,
+               b->shadow_contents);
+         }
        /* FIXME drow/2003-10-07: This doesn't handle any other kinds of
           breakpoints.  It's wrong for watchpoints, for example.  */
        if (val != 0)
@@ -1415,7 +1450,14 @@
            val = target_remove_hw_breakpoint (b->address, 
                                               b->shadow_contents);
          else
-           val = target_remove_breakpoint (b->address, b->shadow_contents);
+           if (-1!=b->owner->thread) {
+             val = target_remove_thread_breakpoint (b->address,
+               b->shadow_contents,
+               ptid_get_pid(thread_id_to_pid(b->owner->thread)));
+           } else {
+             val = target_remove_breakpoint (b->address,
+               b->shadow_contents);
+           }
        }
       else
        {
@@ -1433,7 +1475,14 @@
                if (b->loc_type == bp_loc_hardware_breakpoint)
                  target_remove_hw_breakpoint (addr, b->shadow_contents);
                else
-                 target_remove_breakpoint (addr, b->shadow_contents);
+                 if (-1!=b->owner->thread) {
+                   target_remove_thread_breakpoint (addr,
+                       b->shadow_contents,
+                       ptid_get_pid(thread_id_to_pid(b->owner->thread)));
+               } else {
+                   target_remove_breakpoint (addr,
+                       b->shadow_contents);
+               }
              }
          /* Did we set a breakpoint at the VMA? 
             If so, we will have marked the breakpoint 'inserted'.  */
@@ -1447,8 +1496,14 @@
                val = target_remove_hw_breakpoint (b->address, 
                                                   b->shadow_contents);
              else
-               val = target_remove_breakpoint (b->address,
-                                               b->shadow_contents);
+               if (-1!=b->owner->thread) {
+                 val = target_remove_thread_breakpoint (b->address,
+                     b->shadow_contents,
+                     ptid_get_pid(thread_id_to_pid(b->owner->thread)));
+               } else {
+                 val = target_remove_breakpoint (b->address,
+                     b->shadow_contents);
+               }
            }
          else
            {
@@ -1557,7 +1612,14 @@
           && !b->duplicate)
     {
 
-      val = target_remove_breakpoint (b->address, b->shadow_contents);
+      if (-1!=b->owner->thread) {
+       val = target_remove_thread_breakpoint (b->address,
+           b->shadow_contents,
+           ptid_get_pid(thread_id_to_pid(b->owner->thread)));
+      } else {
+       val = target_remove_breakpoint (b->address,
+           b->shadow_contents);
+      }
       if (val)
        return val;
 
@@ -6949,7 +7011,14 @@
          if (b->type == bp_hardware_breakpoint)
            val = target_insert_hw_breakpoint (b->loc->address, b->loc->shadow_contents);
          else
-           val = target_insert_breakpoint (b->loc->address, b->loc->shadow_contents);
+           if (-1!=b->thread) {
+             val = target_insert_thread_breakpoint (b->loc->address,
+                 b->loc->shadow_contents,
+                 ptid_get_pid (thread_id_to_pid (b->thread)));
+           } else {
+             val = target_insert_breakpoint (b->loc->address,
+                 b->loc->shadow_contents);
+           }
 
          /* If there was an error in the insert, print a message, then stop execution.  */
          if (val != 0)
diff -ru gdb-6.1.1o/gdb/corelow.c gdb-6.1.1/gdb/corelow.c
--- gdb-6.1.1o/gdb/corelow.c    2004-02-28 19:04:36.000000000 +0100
+++ gdb-6.1.1/gdb/corelow.c     2004-09-10 10:16:12.296875000 +0200
@@ -614,6 +614,8 @@
   core_ops.to_files_info = core_files_info;
   core_ops.to_insert_breakpoint = ignore;
   core_ops.to_remove_breakpoint = ignore;
+  core_ops.to_insert_thread_breakpoint = NULL;
+  core_ops.to_remove_thread_breakpoint = NULL;
   core_ops.to_create_inferior = find_default_create_inferior;
   core_ops.to_thread_alive = core_file_thread_alive;
   core_ops.to_stratum = core_stratum;
diff -ru gdb-6.1.1o/gdb/exec.c gdb-6.1.1/gdb/exec.c
--- gdb-6.1.1o/gdb/exec.c       2004-02-28 19:04:37.000000000 +0100
+++ gdb-6.1.1/gdb/exec.c        2004-09-10 10:26:37.125000000 +0200
@@ -705,6 +705,8 @@
   exec_ops.to_files_info = exec_files_info;
   exec_ops.to_insert_breakpoint = ignore;
   exec_ops.to_remove_breakpoint = ignore;
+  exec_ops.to_insert_thread_breakpoint = NULL;
+  exec_ops.to_remove_thread_breakpoint = NULL;
   exec_ops.to_create_inferior = find_default_create_inferior;
   exec_ops.to_stratum = file_stratum;
   exec_ops.to_has_memory = 1;
diff -ru gdb-6.1.1o/gdb/gnu-nat.c gdb-6.1.1/gdb/gnu-nat.c
--- gdb-6.1.1o/gdb/gnu-nat.c    2003-09-30 15:23:49.000000000 +0200
+++ gdb-6.1.1/gdb/gnu-nat.c     2004-09-10 10:26:10.359375000 +0200
@@ -2604,6 +2604,8 @@
   gnu_ops.to_find_memory_regions = gnu_find_memory_regions;
   gnu_ops.to_insert_breakpoint = memory_insert_breakpoint;
   gnu_ops.to_remove_breakpoint = memory_remove_breakpoint;
+  gnu_ops.to_insert_thread_breakpoint = NULL;
+  gnu_ops.to_remove_thread_breakpoint = NULL;
   gnu_ops.to_terminal_init = gnu_terminal_init_inferior;
   gnu_ops.to_terminal_inferior = terminal_inferior;
   gnu_ops.to_terminal_ours_for_output = terminal_ours_for_output;
diff -ru gdb-6.1.1o/gdb/go32-nat.c gdb-6.1.1/gdb/go32-nat.c
--- gdb-6.1.1o/gdb/go32-nat.c   2003-12-29 08:42:43.000000000 +0100
+++ gdb-6.1.1/gdb/go32-nat.c    2004-09-10 10:24:54.140625000 +0200
@@ -863,6 +863,8 @@
   go32_ops.to_files_info = go32_files_info;
   go32_ops.to_insert_breakpoint = memory_insert_breakpoint;
   go32_ops.to_remove_breakpoint = memory_remove_breakpoint;
+  go32_ops.to_insert_thread_breakpoint = NULL;
+  go32_ops.to_remove_thread_breakpoint = NULL;
   go32_ops.to_terminal_init = go32_terminal_init;
   go32_ops.to_terminal_inferior = go32_terminal_inferior;
   go32_ops.to_terminal_ours_for_output = go32_terminal_ours;
diff -ru gdb-6.1.1o/gdb/hpux-thread.c gdb-6.1.1/gdb/hpux-thread.c
--- gdb-6.1.1o/gdb/hpux-thread.c        2003-10-02 22:28:29.000000000 +0200
+++ gdb-6.1.1/gdb/hpux-thread.c 2004-09-10 10:24:24.406250000 +0200
@@ -551,6 +551,8 @@
   hpux_thread_ops.to_files_info = hpux_thread_files_info;
   hpux_thread_ops.to_insert_breakpoint = memory_insert_breakpoint;
   hpux_thread_ops.to_remove_breakpoint = memory_remove_breakpoint;
+  hpux_thread_ops.to_insert_thread_breakpoint = NULL;
+  hpux_thread_ops.to_remove_thread_breakpoint = NULL;
   hpux_thread_ops.to_terminal_init = terminal_init_inferior;
   hpux_thread_ops.to_terminal_inferior = terminal_inferior;
   hpux_thread_ops.to_terminal_ours_for_output = terminal_ours_for_output;
diff -ru gdb-6.1.1o/gdb/inftarg.c gdb-6.1.1/gdb/inftarg.c
--- gdb-6.1.1o/gdb/inftarg.c    2004-02-04 22:49:55.000000000 +0100
+++ gdb-6.1.1/gdb/inftarg.c     2004-09-10 10:24:02.484375000 +0200
@@ -626,6 +626,8 @@
   child_ops.to_files_info = child_files_info;
   child_ops.to_insert_breakpoint = memory_insert_breakpoint;
   child_ops.to_remove_breakpoint = memory_remove_breakpoint;
+  child_ops.to_insert_thread_breakpoint = NULL;
+  child_ops.to_remove_thread_breakpoint = NULL;
   child_ops.to_terminal_init = terminal_init_inferior;
   child_ops.to_terminal_inferior = terminal_inferior;
   child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
diff -ru gdb-6.1.1o/gdb/monitor.c gdb-6.1.1/gdb/monitor.c
--- gdb-6.1.1o/gdb/monitor.c    2004-01-21 16:37:11.000000000 +0100
+++ gdb-6.1.1/gdb/monitor.c     2004-09-10 10:23:38.140625000 +0200
@@ -2259,6 +2259,8 @@
   monitor_ops.to_files_info = monitor_files_info;
   monitor_ops.to_insert_breakpoint = monitor_insert_breakpoint;
   monitor_ops.to_remove_breakpoint = monitor_remove_breakpoint;
+  monitor_ops.to_insert_thread_breakpoint = NULL;
+  monitor_ops.to_remove_thread_breakpoint = NULL;
   monitor_ops.to_kill = monitor_kill;
   monitor_ops.to_load = monitor_load;
   monitor_ops.to_create_inferior = monitor_create_inferior;
diff -ru gdb-6.1.1o/gdb/nto-procfs.c gdb-6.1.1/gdb/nto-procfs.c
--- gdb-6.1.1o/gdb/nto-procfs.c 2003-07-18 19:15:33.000000000 +0200
+++ gdb-6.1.1/gdb/nto-procfs.c  2004-09-10 10:22:47.171875000 +0200
@@ -1275,6 +1275,8 @@
   procfs_ops.to_files_info = procfs_files_info;
   procfs_ops.to_insert_breakpoint = procfs_insert_breakpoint;
   procfs_ops.to_remove_breakpoint = procfs_remove_breakpoint;
+  procfs_ops.to_insert_thread_breakpoint = NULL;
+  procfs_ops.to_remove_thread_breakpoint = NULL;
   procfs_ops.to_can_use_hw_breakpoint = procfs_can_use_hw_breakpoint;
   procfs_ops.to_insert_hw_breakpoint = procfs_insert_hw_breakpoint;
   procfs_ops.to_remove_hw_breakpoint = procfs_remove_breakpoint;
diff -ru gdb-6.1.1o/gdb/ppc-bdm.c gdb-6.1.1/gdb/ppc-bdm.c
--- gdb-6.1.1o/gdb/ppc-bdm.c    2003-09-17 16:24:30.000000000 +0200
+++ gdb-6.1.1/gdb/ppc-bdm.c     2004-09-10 10:26:59.671875000 +0200
@@ -331,6 +331,8 @@
   bdm_ppc_ops.to_files_info = ocd_files_info;
   bdm_ppc_ops.to_insert_breakpoint = ocd_insert_breakpoint;
   bdm_ppc_ops.to_remove_breakpoint = ocd_remove_breakpoint;
+  bdm_ppc_ops.to_insert_thread_breakpoint = NULL;
+  bdm_ppc_ops.to_remove_thread_breakpoint = NULL;
   bdm_ppc_ops.to_kill = ocd_kill;
   bdm_ppc_ops.to_load = ocd_load;
   bdm_ppc_ops.to_create_inferior = ocd_create_inferior;
diff -ru gdb-6.1.1o/gdb/procfs.c gdb-6.1.1/gdb/procfs.c
--- gdb-6.1.1o/gdb/procfs.c     2004-02-15 23:38:40.000000000 +0100
+++ gdb-6.1.1/gdb/procfs.c      2004-09-10 10:15:43.656250000 +0200
@@ -175,6 +175,8 @@
   procfs_ops.to_xfer_memory         = procfs_xfer_memory;
   procfs_ops.to_insert_breakpoint   =  memory_insert_breakpoint;
   procfs_ops.to_remove_breakpoint   =  memory_remove_breakpoint;
+  procfs_ops.to_insert_thread_breakpoint   =  NULL;
+  procfs_ops.to_remove_thread_breakpoint   =  NULL;
   procfs_ops.to_notice_signals      = procfs_notice_signals;
   procfs_ops.to_files_info          = procfs_files_info;
   procfs_ops.to_stop                = procfs_stop;
diff -ru gdb-6.1.1o/gdb/remote-e7000.c gdb-6.1.1/gdb/remote-e7000.c
--- gdb-6.1.1o/gdb/remote-e7000.c       2003-12-11 07:21:12.000000000 +0100
+++ gdb-6.1.1/gdb/remote-e7000.c        2004-09-10 10:15:13.000000000 +0200
@@ -2153,6 +2153,8 @@
   e7000_ops.to_files_info = e7000_files_info;
   e7000_ops.to_insert_breakpoint = e7000_insert_breakpoint;
   e7000_ops.to_remove_breakpoint = e7000_remove_breakpoint;
+  e7000_ops.to_insert_thread_breakpoint = NULL;
+  e7000_ops.to_remove_thread_breakpoint = NULL;
   e7000_ops.to_kill = e7000_kill;
   e7000_ops.to_load = e7000_load;
   e7000_ops.to_create_inferior = e7000_create_inferior;
diff -ru gdb-6.1.1o/gdb/remote-m32r-sdi.c gdb-6.1.1/gdb/remote-m32r-sdi.c
--- gdb-6.1.1o/gdb/remote-m32r-sdi.c    2004-03-10 01:22:45.000000000 +0100
+++ gdb-6.1.1/gdb/remote-m32r-sdi.c     2004-09-10 09:31:47.937500000 +0200
@@ -1619,6 +1619,8 @@
   m32r_ops.to_files_info = m32r_files_info;
   m32r_ops.to_insert_breakpoint = m32r_insert_breakpoint;
   m32r_ops.to_remove_breakpoint = m32r_remove_breakpoint;
+  m32r_ops.to_insert_thread_breakpoint = NULL;
+  m32r_ops.to_remove_thread_breakpoint = NULL;
   m32r_ops.to_can_use_hw_breakpoint = m32r_can_use_hw_watchpoint;
   m32r_ops.to_insert_watchpoint = m32r_insert_watchpoint;
   m32r_ops.to_remove_watchpoint = m32r_remove_watchpoint;
diff -ru gdb-6.1.1o/gdb/remote-mips.c gdb-6.1.1/gdb/remote-mips.c
--- gdb-6.1.1o/gdb/remote-mips.c        2004-01-21 16:37:11.000000000 +0100
+++ gdb-6.1.1/gdb/remote-mips.c 2004-09-10 09:32:15.812500000 +0200
@@ -3310,6 +3310,8 @@
   mips_ops.to_files_info = mips_files_info;
   mips_ops.to_insert_breakpoint = mips_insert_breakpoint;
   mips_ops.to_remove_breakpoint = mips_remove_breakpoint;
+  mips_ops.to_insert_thread_breakpoint = NULL;
+  mips_ops.to_remove_thread_breakpoint = NULL;
   mips_ops.to_insert_watchpoint = mips_insert_watchpoint;
   mips_ops.to_remove_watchpoint = mips_remove_watchpoint;
   mips_ops.to_stopped_by_watchpoint = mips_stopped_by_watchpoint;
diff -ru gdb-6.1.1o/gdb/remote-rdi.c gdb-6.1.1/gdb/remote-rdi.c
--- gdb-6.1.1o/gdb/remote-rdi.c 2004-02-12 19:43:09.000000000 +0100
+++ gdb-6.1.1/gdb/remote-rdi.c  2004-09-10 09:32:34.421875000 +0200
@@ -905,6 +905,8 @@
   arm_rdi_ops.to_files_info = arm_rdi_files_info;
   arm_rdi_ops.to_insert_breakpoint = arm_rdi_insert_breakpoint;
   arm_rdi_ops.to_remove_breakpoint = arm_rdi_remove_breakpoint;
+  arm_rdi_ops.to_insert_breakpoint = NULL;
+  arm_rdi_ops.to_remove_breakpoint = NULL;
   arm_rdi_ops.to_kill = arm_rdi_kill;
   arm_rdi_ops.to_load = generic_load;
   arm_rdi_ops.to_create_inferior = arm_rdi_create_inferior;
diff -ru gdb-6.1.1o/gdb/remote-rdp.c gdb-6.1.1/gdb/remote-rdp.c
--- gdb-6.1.1o/gdb/remote-rdp.c 2004-03-25 18:03:59.000000000 +0100
+++ gdb-6.1.1/gdb/remote-rdp.c  2004-09-10 09:35:50.562500000 +0200
@@ -1408,6 +1408,8 @@
   remote_rdp_ops.to_files_info = remote_rdp_files_info;
   remote_rdp_ops.to_insert_breakpoint = remote_rdp_insert_breakpoint;
   remote_rdp_ops.to_remove_breakpoint = remote_rdp_remove_breakpoint;
+  remote_rdp_ops.to_insert_thread_breakpoint = NULL;
+  remote_rdp_ops.to_remove_thread_breakpoint = NULL;
   remote_rdp_ops.to_kill = remote_rdp_kill;
   remote_rdp_ops.to_load = generic_load;
   remote_rdp_ops.to_create_inferior = remote_rdp_create_inferior;
diff -ru gdb-6.1.1o/gdb/remote-sds.c gdb-6.1.1/gdb/remote-sds.c
--- gdb-6.1.1o/gdb/remote-sds.c 2004-01-19 02:20:11.000000000 +0100
+++ gdb-6.1.1/gdb/remote-sds.c  2004-09-10 09:36:12.234375000 +0200
@@ -1070,6 +1070,8 @@
   sds_ops.to_files_info = sds_files_info;
   sds_ops.to_insert_breakpoint = sds_insert_breakpoint;
   sds_ops.to_remove_breakpoint = sds_remove_breakpoint;
+  sds_ops.to_insert_thread_breakpoint = NULL;
+  sds_ops.to_remove_thread_breakpoint = NULL;
   sds_ops.to_kill = sds_kill;
   sds_ops.to_load = sds_load;
   sds_ops.to_create_inferior = sds_create_inferior;
diff -ru gdb-6.1.1o/gdb/remote-sim.c gdb-6.1.1/gdb/remote-sim.c
--- gdb-6.1.1o/gdb/remote-sim.c 2004-02-02 17:14:36.000000000 +0100
+++ gdb-6.1.1/gdb/remote-sim.c  2004-09-10 09:38:51.375000000 +0200
@@ -871,6 +871,8 @@
   gdbsim_ops.to_files_info = gdbsim_files_info;
   gdbsim_ops.to_insert_breakpoint = gdbsim_insert_breakpoint;
   gdbsim_ops.to_remove_breakpoint = gdbsim_remove_breakpoint;
+  gdbsim_ops.to_insert_thread_breakpoint = NULL;
+  gdbsim_ops.to_remove_thread_breakpoint = NULL;
   gdbsim_ops.to_kill = gdbsim_kill;
   gdbsim_ops.to_load = gdbsim_load;
   gdbsim_ops.to_create_inferior = gdbsim_create_inferior;
diff -ru gdb-6.1.1o/gdb/remote-st.c gdb-6.1.1/gdb/remote-st.c
--- gdb-6.1.1o/gdb/remote-st.c  2003-09-19 00:39:21.000000000 +0200
+++ gdb-6.1.1/gdb/remote-st.c   2004-09-10 09:46:18.875000000 +0200
@@ -778,6 +778,8 @@
   st2000_ops.to_files_info = st2000_files_info;
   st2000_ops.to_insert_breakpoint = st2000_insert_breakpoint;
   st2000_ops.to_remove_breakpoint = st2000_remove_breakpoint;  /* Breakpoints */
+  st2000_ops.to_insert_thread_breakpoint = NULL;
+  st2000_ops.to_remove_thread_breakpoint = NULL;       /* Breakpoints */
   st2000_ops.to_kill = st2000_kill;
   st2000_ops.to_create_inferior = st2000_create_inferior;
   st2000_ops.to_mourn_inferior = st2000_mourn_inferior;
diff -ru gdb-6.1.1o/gdb/remote-vx.c gdb-6.1.1/gdb/remote-vx.c
--- gdb-6.1.1o/gdb/remote-vx.c  2003-09-21 03:26:45.000000000 +0200
+++ gdb-6.1.1/gdb/remote-vx.c   2004-09-10 09:39:52.859375000 +0200
@@ -1380,6 +1380,8 @@
   vx_run_ops.to_files_info = vx_run_files_info;
   vx_run_ops.to_insert_breakpoint = vx_insert_breakpoint;
   vx_run_ops.to_remove_breakpoint = vx_remove_breakpoint;
+  vx_run_ops.to_insert_thread_breakpoint = NULL;
+  vx_run_ops.to_remove_thread_breakpoint = NULL;
   vx_run_ops.to_kill = vx_kill;
   vx_run_ops.to_load = vx_load_command;
   vx_run_ops.to_lookup_symbol = vx_lookup_symbol;
diff -ru gdb-6.1.1o/gdb/remote.c gdb-6.1.1/gdb/remote.c
--- gdb-6.1.1o/gdb/remote.c     2004-02-25 21:41:00.000000000 +0100
+++ gdb-6.1.1/gdb/remote.c      2004-09-13 14:51:34.515625000 +0200
@@ -146,6 +146,10 @@
 
 static int remote_remove_breakpoint (CORE_ADDR, char *);
 
+static int remote_insert_thread_breakpoint (CORE_ADDR, char *, int);
+
+static int remote_remove_thread_breakpoint (CORE_ADDR, char *, int);
+
 static int hexnumlen (ULONGEST num);
 
 static void init_remote_ops (void);
@@ -837,6 +841,7 @@
   Z_PACKET_WRITE_WP,
   Z_PACKET_READ_WP,
   Z_PACKET_ACCESS_WP,
+  Z_PACKET_SOFTWARE_THREAD_BP,
   NR_Z_PACKET_TYPES
 };
 
@@ -915,6 +920,21 @@
   show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_ACCESS_WP]);
 }
 
+static void
+set_remote_protocol_Z_software_thread_bp_packet_cmd (char *args, int from_tty,
+                                             struct cmd_list_element *c)
+{
+  update_packet_config (&remote_protocol_Z[Z_PACKET_SOFTWARE_THREAD_BP]);
+}
+
+static void
+show_remote_protocol_Z_software_thread_bp_packet_cmd (char *args, int from_tty,
+                                              struct cmd_list_element *c)
+{
+  show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_SOFTWARE_THREAD_BP]);
+}
+
+
 /* For compatibility with older distributions.  Provide a ``set remote
    Z-packet ...'' command that updates all the Z packet types. */
 
@@ -4729,6 +4749,86 @@
                  "remote_remove_hw_breakpoint: reached end of function");
 }
 
+static int
+remote_insert_thread_breakpoint (CORE_ADDR addr, char *contents_cache, int threadid)
+{
+  struct remote_state *rs = get_remote_state ();
+  int bp_size;
+
+  /* Try the "Z" s/w breakpoint packet if it is not already disabled.
+     If it succeeds, then set the support to PACKET_ENABLE.  If it
+     fails, and the user has explicitly requested the Z support then
+     report an error, otherwise, mark it disabled and go on. */
+
+  if ((remote_protocol_Z[Z_PACKET_SOFTWARE_THREAD_BP].support != PACKET_DISABLE)
+       &&(-1!=threadid))
+    {
+      char *buf = alloca (rs->remote_packet_size);
+      char *p = buf;
+
+      addr = remote_address_masked (addr);
+      *(p++) = 'Z';
+      *(p++) = '5';
+      *(p++) = ',';
+      p += hexnumstr (p, (ULONGEST) addr);
+      BREAKPOINT_FROM_PC (&addr, &bp_size);
+      sprintf (p, ",%d", bp_size);
+      p+=strlen(p);
+      sprintf (p, ",%x", threadid);
+
+      putpkt (buf);
+      getpkt (buf, (rs->remote_packet_size), 0);
+
+      switch (packet_ok (buf, &remote_protocol_Z[Z_PACKET_SOFTWARE_THREAD_BP]))
+       {
+       case PACKET_ERROR:
+         return -1;
+       case PACKET_OK:
+         return 0;
+       case PACKET_UNKNOWN:
+         break;
+       }
+    }
+
+    /* thread breakpoint not available, use normal breakpoint. */
+    return remote_insert_breakpoint (addr, contents_cache);
+}
+
+static int
+remote_remove_thread_breakpoint (CORE_ADDR addr, char *contents_cache, int threadid)
+{
+  struct remote_state *rs = get_remote_state ();
+  int bp_size;
+
+  if ((remote_protocol_Z[Z_PACKET_SOFTWARE_THREAD_BP].support != PACKET_DISABLE)
+       &&(-1!=threadid))
+    {
+      char *buf = alloca (rs->remote_packet_size);
+      char *p = buf;
+
+      *(p++) = 'z';
+      *(p++) = '5';
+      *(p++) = ',';
+
+      addr = remote_address_masked (addr);
+      p += hexnumstr (p, (ULONGEST) addr);
+      BREAKPOINT_FROM_PC (&addr, &bp_size);
+      sprintf (p, ",%d", bp_size);
+      p+=strlen(p);
+      sprintf (p, ",%x", threadid);
+
+      putpkt (buf);
+      getpkt (buf, (rs->remote_packet_size), 0);
+
+      return (buf[0] == 'E');
+    }
+
+    /* thread breakpoint not available, use normal breakpoint. */
+    return remote_remove_breakpoint (addr, contents_cache);
+
+}
+
+
 /* Some targets are only capable of doing downloads, and afterwards
    they switch to the remote serial protocol.  This function provides
    a clean way to get from the download target to the remote target.
@@ -5240,6 +5340,8 @@
   remote_ops.to_remove_hw_breakpoint = remote_remove_hw_breakpoint;
   remote_ops.to_insert_watchpoint = remote_insert_watchpoint;
   remote_ops.to_remove_watchpoint = remote_remove_watchpoint;
+  remote_ops.to_insert_thread_breakpoint = remote_insert_thread_breakpoint;
+  remote_ops.to_remove_thread_breakpoint = remote_remove_thread_breakpoint;
   remote_ops.to_kill = remote_kill;
   remote_ops.to_load = generic_load;
   remote_ops.to_mourn_inferior = remote_mourn;
@@ -5666,6 +5768,13 @@
                         &remote_set_cmdlist, &remote_show_cmdlist,
                         0);
 
+  add_packet_config_cmd (&remote_protocol_Z[Z_PACKET_SOFTWARE_THREAD_BP],
+                        "Z5", "software-thread-breakpoint",
+                        set_remote_protocol_Z_software_thread_bp_packet_cmd,
+                        show_remote_protocol_Z_software_thread_bp_packet_cmd,
+                        &remote_set_cmdlist, &remote_show_cmdlist,
+                        0);
+
   add_packet_config_cmd (&remote_protocol_qPart_auxv,
                         "qPart_auxv", "read-aux-vector",
                         set_remote_protocol_qPart_auxv_packet_cmd,
diff -ru gdb-6.1.1o/gdb/sol-thread.c gdb-6.1.1/gdb/sol-thread.c
--- gdb-6.1.1o/gdb/sol-thread.c 2004-02-01 23:35:28.000000000 +0100
+++ gdb-6.1.1/gdb/sol-thread.c  2004-09-10 09:45:52.156250000 +0200
@@ -1584,6 +1584,8 @@
   sol_thread_ops.to_files_info = sol_thread_files_info;
   sol_thread_ops.to_insert_breakpoint = memory_insert_breakpoint;
   sol_thread_ops.to_remove_breakpoint = memory_remove_breakpoint;
+  sol_thread_ops.to_insert_thread_breakpoint = NULL;
+  sol_thread_ops.to_remove_thread_breakpoint = NULL;
   sol_thread_ops.to_terminal_init = terminal_init_inferior;
   sol_thread_ops.to_terminal_inferior = terminal_inferior;
   sol_thread_ops.to_terminal_ours_for_output = terminal_ours_for_output;
@@ -1628,6 +1630,8 @@
   sol_core_ops.to_files_info = sol_core_files_info;
   sol_core_ops.to_insert_breakpoint = ignore;
   sol_core_ops.to_remove_breakpoint = ignore;
+  sol_core_ops.to_insert_thread_breakpoint = NULL;
+  sol_core_ops.to_remove_thread_breakpoint = NULL;
   sol_core_ops.to_create_inferior = sol_thread_create_inferior;
   sol_core_ops.to_stratum = core_stratum;
   sol_core_ops.to_has_memory = 1;
diff -ru gdb-6.1.1o/gdb/target.c gdb-6.1.1/gdb/target.c
--- gdb-6.1.1o/gdb/target.c     2004-01-19 17:49:35.000000000 +0100
+++ gdb-6.1.1/gdb/target.c      2004-09-10 10:31:29.156250000 +0200
@@ -117,6 +117,10 @@
 
 static int debug_to_remove_breakpoint (CORE_ADDR, char *);
 
+static int debug_to_insert_thread_breakpoint (CORE_ADDR, char *, int);
+
+static int debug_to_remove_thread_breakpoint (CORE_ADDR, char *, int);
+
 static int debug_to_can_use_hw_breakpoint (int, int, int);
 
 static int debug_to_insert_hw_breakpoint (CORE_ADDR, char *);
@@ -390,6 +394,8 @@
       INHERIT (to_files_info, t);
       INHERIT (to_insert_breakpoint, t);
       INHERIT (to_remove_breakpoint, t);
+      INHERIT (to_insert_thread_breakpoint, t);
+      INHERIT (to_remove_thread_breakpoint, t);
       INHERIT (to_can_use_hw_breakpoint, t);
       INHERIT (to_insert_hw_breakpoint, t);
       INHERIT (to_remove_hw_breakpoint, t);
@@ -506,6 +512,10 @@
            memory_insert_breakpoint);
   de_fault (to_remove_breakpoint, 
            memory_remove_breakpoint);
+  de_fault (to_insert_thread_breakpoint, 
+           NULL);
+  de_fault (to_remove_thread_breakpoint, 
+           NULL);
   de_fault (to_can_use_hw_breakpoint,
            (int (*) (int, int, int))
            return_zero);
@@ -1886,6 +1896,36 @@
 }
 
 static int
+debug_to_insert_thread_breakpoint (CORE_ADDR addr, char *save, int threadid)
+{
+  int retval;
+
+  retval = debug_target.to_insert_thread_breakpoint (addr, save, threadid);
+
+  fprintf_unfiltered (gdb_stdlog,
+                     "target_insert_breakpoint (0x%lx, %lx) = %ld\n",
+                     (unsigned long) addr,
+                     (unsigned long) threadid,
+                     (unsigned long) retval);
+  return retval;
+}
+
+static int
+debug_to_remove_thread_breakpoint (CORE_ADDR addr, char *save, int threadid)
+{
+  int retval;
+
+  retval = debug_target.to_remove_thread_breakpoint (addr, save, threadid);
+
+  fprintf_unfiltered (gdb_stdlog,
+                     "target_remove_thread_breakpoint (0x%lx, %lx) = %ld\n",
+                     (unsigned long) addr,
+                     (unsigned long) threadid,
+                     (unsigned long) retval);
+  return retval;
+}
+
+static int
 debug_to_can_use_hw_breakpoint (int type, int cnt, int from_tty)
 {
   int retval;
@@ -2354,6 +2394,8 @@
   current_target.to_files_info = debug_to_files_info;
   current_target.to_insert_breakpoint = debug_to_insert_breakpoint;
   current_target.to_remove_breakpoint = debug_to_remove_breakpoint;
+  current_target.to_insert_thread_breakpoint = debug_to_insert_thread_breakpoint;
+  current_target.to_remove_thread_breakpoint = debug_to_remove_thread_breakpoint;
   current_target.to_can_use_hw_breakpoint = debug_to_can_use_hw_breakpoint;
   current_target.to_insert_hw_breakpoint = debug_to_insert_hw_breakpoint;
   current_target.to_remove_hw_breakpoint = debug_to_remove_hw_breakpoint;
diff -ru gdb-6.1.1o/gdb/target.h gdb-6.1.1/gdb/target.h
--- gdb-6.1.1o/gdb/target.h     2004-02-04 22:49:55.000000000 +0100
+++ gdb-6.1.1/gdb/target.h      2004-09-10 15:50:36.640625000 +0200
@@ -335,6 +335,8 @@
     void (*to_files_info) (struct target_ops *);
     int (*to_insert_breakpoint) (CORE_ADDR, char *);
     int (*to_remove_breakpoint) (CORE_ADDR, char *);
+    int (*to_insert_thread_breakpoint) (CORE_ADDR, char *, int);
+    int (*to_remove_thread_breakpoint) (CORE_ADDR, char *, int);
     int (*to_can_use_hw_breakpoint) (int, int, int);
     int (*to_insert_hw_breakpoint) (CORE_ADDR, char *);
     int (*to_remove_hw_breakpoint) (CORE_ADDR, char *);
@@ -632,6 +634,11 @@
 #define        target_insert_breakpoint(addr, save)    \
      (*current_target.to_insert_breakpoint) (addr, save)
 
+#define        target_insert_thread_breakpoint(addr, save, threadid)                   \
+    (current_target.to_insert_thread_breakpoint?                               \
+    (*current_target.to_insert_thread_breakpoint) (addr, save, threadid):      \
+    (*current_target.to_insert_breakpoint) (addr, save))
+
 /* Remove a breakpoint at address ADDR in the target machine.
    SAVE is a pointer to the same save area
    that was previously passed to target_insert_breakpoint.
@@ -640,6 +647,11 @@
 #define        target_remove_breakpoint(addr, save)    \
      (*current_target.to_remove_breakpoint) (addr, save)
 
+#define        target_remove_thread_breakpoint(addr, save, threadid)                   \
+    (current_target.to_remove_thread_breakpoint?                               \
+    (*current_target.to_remove_thread_breakpoint) (addr, save, threadid):      \
+    (*current_target.to_remove_breakpoint) (addr, save))
+
 /* Initialize the terminal settings we record for the inferior,
    before we actually run the inferior.  */
 
diff -ru gdb-6.1.1o/gdb/v850ice.c gdb-6.1.1/gdb/v850ice.c
--- gdb-6.1.1o/gdb/v850ice.c    2003-10-02 22:28:30.000000000 +0200
+++ gdb-6.1.1/gdb/v850ice.c     2004-09-10 09:25:18.703125000 +0200
@@ -905,6 +905,8 @@
   v850ice_ops.to_files_info = v850ice_files_info;
   v850ice_ops.to_insert_breakpoint = v850ice_insert_breakpoint;
   v850ice_ops.to_remove_breakpoint = v850ice_remove_breakpoint;
+  v850ice_ops.to_insert_thread_breakpoint = NULL;
+  v850ice_ops.to_remove_thread_breakpoint = NULL;
   v850ice_ops.to_kill = v850ice_kill;
   v850ice_ops.to_load = v850ice_load;
   v850ice_ops.to_mourn_inferior = v850ice_mourn;
diff -ru gdb-6.1.1o/gdb/win32-nat.c gdb-6.1.1/gdb/win32-nat.c
--- gdb-6.1.1o/gdb/win32-nat.c  2004-01-05 20:53:08.000000000 +0100
+++ gdb-6.1.1/gdb/win32-nat.c   2004-09-10 09:24:59.984375000 +0200
@@ -2060,6 +2060,8 @@
   child_ops.to_files_info = child_files_info;
   child_ops.to_insert_breakpoint = memory_insert_breakpoint;
   child_ops.to_remove_breakpoint = memory_remove_breakpoint;
+  child_ops.to_insert_thread_breakpoint = NULL;
+  child_ops.to_remove_thread_breakpoint = NULL;
   child_ops.to_terminal_init = terminal_init_inferior;
   child_ops.to_terminal_inferior = terminal_inferior;
   child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
diff -ru gdb-6.1.1o/gdb/wince.c gdb-6.1.1/gdb/wince.c
--- gdb-6.1.1o/gdb/wince.c      2003-11-06 03:52:28.000000000 +0100
+++ gdb-6.1.1/gdb/wince.c       2004-09-10 09:24:50.343750000 +0200
@@ -1908,6 +1908,8 @@
   child_ops.to_files_info = child_files_info;
   child_ops.to_insert_breakpoint = memory_insert_breakpoint;
   child_ops.to_remove_breakpoint = memory_remove_breakpoint;
+  child_ops.to_insert_thread_breakpoint = NULL;
+  child_ops.to_remove_thread_breakpoint = NULL;
   child_ops.to_terminal_init = terminal_init_inferior;
   child_ops.to_terminal_inferior = terminal_inferior;
   child_ops.to_terminal_ours_for_output = terminal_ours_for_output;



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]