* linux-low.c (linux_wait_for_event): Update messages. Do not
authorDaniel Jacobowitz <drow@false.org>
Tue, 18 Dec 2007 21:58:01 +0000 (21:58 +0000)
committerDaniel Jacobowitz <drow@false.org>
Tue, 18 Dec 2007 21:58:01 +0000 (21:58 +0000)
reinsert auto-delete breakpoints.
* mem-break.c (struct breakpoint): Change return type of handler to
int.
(set_breakpoint_at): Update handler type.
(reinsert_breakpoint_handler): Return 1 instead of calling
delete_breakpoint.
(reinsert_breakpoint_by_bp): Check for the original breakpoint before
setting a new one.
(check_breakpoints): Delete auto-delete breakpoints and return 2.
* mem-break.h (set_breakpoint_at): Update handler type.
* thread-db.c (thread_db_create_event, thread_db_create_event): Update.
* win32-low.c (auto_delete_breakpoint): New.
(get_child_debug_event): Use it.

gdb/gdbserver/ChangeLog
gdb/gdbserver/linux-low.c
gdb/gdbserver/mem-break.c
gdb/gdbserver/mem-break.h
gdb/gdbserver/thread-db.c
gdb/gdbserver/win32-low.c

index 10bf1d0d40f9fc28770dffccc024378ab542005f..7e2cfcda13980d91d8b3756317395c4b36a614b6 100644 (file)
@@ -1,3 +1,20 @@
+2007-12-18  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * linux-low.c (linux_wait_for_event): Update messages.  Do not
+       reinsert auto-delete breakpoints.
+       * mem-break.c (struct breakpoint): Change return type of handler to
+       int.
+       (set_breakpoint_at): Update handler type.
+       (reinsert_breakpoint_handler): Return 1 instead of calling
+       delete_breakpoint.
+       (reinsert_breakpoint_by_bp): Check for the original breakpoint before
+       setting a new one.
+       (check_breakpoints): Delete auto-delete breakpoints and return 2.
+       * mem-break.h (set_breakpoint_at): Update handler type.
+       * thread-db.c (thread_db_create_event, thread_db_create_event): Update.
+       * win32-low.c (auto_delete_breakpoint): New.
+       (get_child_debug_event): Use it.
+
 2007-12-16  Daniel Jacobowitz  <dan@codesourcery.com>
 
        * configure.ac: Check for pread and pwrite.
index b5a0567677a57fe4b89dc6c4e9624d499ab65848..c746269be461f70cc562503a0d1629c417f0d720 100644 (file)
@@ -623,6 +623,7 @@ linux_wait_for_event (struct thread_info *child)
   CORE_ADDR stop_pc;
   struct process_info *event_child;
   int wstat;
+  int bp_status;
 
   /* Check for a process with a pending status.  */
   /* It is possible that the user changed the pending task's registers since
@@ -786,18 +787,20 @@ linux_wait_for_event (struct thread_info *child)
          continue;
        }
 
-      if (debug_threads)
-       fprintf (stderr, "Hit a (non-reinsert) breakpoint.\n");
+      bp_status = check_breakpoints (stop_pc);
 
-      if (check_breakpoints (stop_pc) != 0)
+      if (bp_status != 0)
        {
+         if (debug_threads)
+           fprintf (stderr, "Hit a gdbserver breakpoint.\n");
+
          /* We hit one of our own breakpoints.  We mark it as a pending
             breakpoint, so that check_removed_breakpoint () will do the PC
             adjustment for us at the appropriate time.  */
          event_child->pending_is_breakpoint = 1;
          event_child->pending_stop_pc = stop_pc;
 
-         /* Now we need to put the breakpoint back.  We continue in the event
+         /* We may need to put the breakpoint back.  We continue in the event
             loop instead of simply replacing the breakpoint right away,
             in order to not lose signals sent to the thread that hit the
             breakpoint.  Unfortunately this increases the window where another
@@ -815,7 +818,10 @@ linux_wait_for_event (struct thread_info *child)
             Otherwise, call the target function to figure out where we need
             our temporary breakpoint, create it, and continue executing this
             process.  */
-         if (the_low_target.breakpoint_reinsert_addr == NULL)
+         if (bp_status == 2)
+           /* No need to reinsert.  */
+           linux_resume_one_process (&event_child->head, 0, 0, NULL);
+         else if (the_low_target.breakpoint_reinsert_addr == NULL)
            {
              event_child->bp_reinsert = stop_pc;
              uninsert_breakpoint (stop_pc);
@@ -831,6 +837,9 @@ linux_wait_for_event (struct thread_info *child)
          continue;
        }
 
+      if (debug_threads)
+       fprintf (stderr, "Hit a non-gdbserver breakpoint.\n");
+
       /* If we were single-stepping, we definitely want to report the
         SIGTRAP.  The single-step operation has completed, so also
          clear the stepping flag; in general this does not matter,
index 5cdb3d9ce667258821fc0021627cd31db30ef793..f32d5a66fb4e016a05f01df12265544521956357 100644 (file)
@@ -39,14 +39,16 @@ struct breakpoint
      in the *next chain somewhere).  */
   struct breakpoint *breakpoint_to_reinsert;
 
-  /* Function to call when we hit this breakpoint.  */
-  void (*handler) (CORE_ADDR);
+  /* Function to call when we hit this breakpoint.  If it returns 1,
+     the breakpoint will be deleted; 0, it will be reinserted for
+     another round.  */
+  int (*handler) (CORE_ADDR);
 };
 
 struct breakpoint *breakpoints;
 
 void
-set_breakpoint_at (CORE_ADDR where, void (*handler) (CORE_ADDR))
+set_breakpoint_at (CORE_ADDR where, int (*handler) (CORE_ADDR))
 {
   struct breakpoint *bp;
 
@@ -119,7 +121,7 @@ delete_breakpoint_at (CORE_ADDR addr)
     delete_breakpoint (bp);
 }
 
-static void
+static int
 reinsert_breakpoint_handler (CORE_ADDR stop_pc)
 {
   struct breakpoint *stop_bp, *orig_bp;
@@ -135,7 +137,7 @@ reinsert_breakpoint_handler (CORE_ADDR stop_pc)
   (*the_target->write_memory) (orig_bp->pc, breakpoint_data,
                               breakpoint_len);
   orig_bp->reinserting = 0;
-  delete_breakpoint (stop_bp);
+  return 1;
 }
 
 void
@@ -143,12 +145,12 @@ reinsert_breakpoint_by_bp (CORE_ADDR stop_pc, CORE_ADDR stop_at)
 {
   struct breakpoint *bp, *orig_bp;
 
-  set_breakpoint_at (stop_at, reinsert_breakpoint_handler);
-
   orig_bp = find_breakpoint_at (stop_pc);
   if (orig_bp == NULL)
     error ("Could not find original breakpoint in list.");
 
+  set_breakpoint_at (stop_at, reinsert_breakpoint_handler);
+
   bp = find_breakpoint_at (stop_at);
   if (bp == NULL)
     error ("Could not find breakpoint in list (reinserting by breakpoint).");
@@ -203,8 +205,13 @@ check_breakpoints (CORE_ADDR stop_pc)
       return 0;
     }
 
-  (*bp->handler) (bp->pc);
-  return 1;
+  if ((*bp->handler) (bp->pc))
+    {
+      delete_breakpoint (bp);
+      return 2;
+    }
+  else
+    return 1;
 }
 
 void
index 1d2e9d9879e8ca6c320e9a7949553e0dfb786d26..dbb30ae9abcd241d40c16730e80782020282c435 100644 (file)
 /* Breakpoints are opaque.  */
 
 /* Create a new breakpoint at WHERE, and call HANDLER when
-   it is hit.  */
+   it is hit.  HANDLER should return 1 if the breakpoint
+   should be deleted, 0 otherwise.  */
 
 void set_breakpoint_at (CORE_ADDR where,
-                       void (*handler) (CORE_ADDR));
+                       int (*handler) (CORE_ADDR));
 
 /* Delete a breakpoint previously inserted at ADDR with
    set_breakpoint_at.  */
index 1869dbdf8f507d6e316c832d91db3ba292ad16b8..3128338ab3e95f0564aa4cad1bbf0c8c1781b9fc 100644 (file)
@@ -130,7 +130,7 @@ thread_db_state_str (td_thr_state_e state)
 }
 #endif
 
-static void
+static int
 thread_db_create_event (CORE_ADDR where)
 {
   td_event_msg_t msg;
@@ -159,14 +159,18 @@ thread_db_create_event (CORE_ADDR where)
   /* msg.event == TD_EVENT_CREATE */
 
   find_new_threads_callback (msg.th_p, NULL);
+
+  return 0;
 }
 
 #if 0
-static void
+static int
 thread_db_death_event (CORE_ADDR where)
 {
   if (debug_threads)
     fprintf (stderr, "Thread death event.\n");
+
+  return 0;
 }
 #endif
 
index 1c81804c2cfce8c17472cc68949eb49b806b6dce..be60492d8f4b5983197642be5a9290581ce1b02f 100644 (file)
@@ -1334,6 +1334,14 @@ fake_breakpoint_event (void)
   for_each_inferior (&all_threads, suspend_one_thread);
 }
 
+#ifdef _WIN32_WCE
+static int
+auto_delete_breakpoint (CORE_ADDR stop_pc)
+{
+  return 1;
+}
+#endif
+
 /* Get the next event from the child.  */
 
 static int
@@ -1445,7 +1453,7 @@ get_child_debug_event (struct target_waitstatus *ourstatus)
             it is hit.  */
          set_breakpoint_at ((CORE_ADDR) (long) current_event.u
                             .CreateProcessInfo.lpStartAddress,
-                            delete_breakpoint_at);
+                            auto_delete_breakpoint);
        }
 #endif
       break;