public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 2/4] Introduce 'enum remove_bp_reason'
  2016-02-14 18:37 [PATCH 0/4] Fix PR gdb/19187 (process record over a fork causes internal error) Pedro Alves
  2016-02-14 18:37 ` [PATCH 3/4] Plumb enum remove_bp_reason all the way to target_remove_breakpoint Pedro Alves
  2016-02-14 18:37 ` [PATCH 1/4] Simplify remove_breakpoint interface Pedro Alves
@ 2016-02-14 18:37 ` Pedro Alves
  2016-02-14 18:44 ` [PATCH 4/4] Fix PR gdb/19187 (process record over a fork causes internal error) Pedro Alves
  2016-08-10 22:11 ` [PATCH 0/4] " Pedro Alves
  4 siblings, 0 replies; 8+ messages in thread
From: Pedro Alves @ 2016-02-14 18:37 UTC (permalink / raw)
  To: gdb-patches

Makes the code more obvious.

gdb/ChangeLog:
2016-02-14  Pedro Alves  <palves@redhat.com>

	* breakpoint.c (insertion_state_t): Delete.
	(enum remove_bp_reason): New.
	(detach_breakpoints, remove_breakpoint_1, remove_breakpoint):
	Adjust to use enum remove_bp_reason instead of insertion_state_t.
---
 gdb/breakpoint.c | 33 +++++++++++++++++++--------------
 1 file changed, 19 insertions(+), 14 deletions(-)

diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 05da8ed..9b37508 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -194,15 +194,20 @@ static void commands_command (char *, int);
 
 static void condition_command (char *, int);
 
-typedef enum
-  {
-    mark_inserted,
-    mark_uninserted
-  }
-insertion_state_t;
+/* Why are we removing the breakpoint from the target?  */
+
+enum remove_bp_reason
+{
+  /* A regular remove.  Remove the breakpoint and forget everything
+     about it.  */
+  REMOVE_BREAKPOINT,
+
+  /* Detach the breakpoints from a fork child.  */
+  DETACH_BREAKPOINT,
+};
 
 static int remove_breakpoint (struct bp_location *);
-static int remove_breakpoint_1 (struct bp_location *, insertion_state_t);
+static int remove_breakpoint_1 (struct bp_location *, enum remove_bp_reason);
 
 static enum print_stop_action print_bp_stop_message (bpstat bs);
 
@@ -3922,7 +3927,7 @@ detach_breakpoints (ptid_t ptid)
       continue;
 
     if (bl->inserted)
-      val |= remove_breakpoint_1 (bl, mark_inserted);
+      val |= remove_breakpoint_1 (bl, DETACH_BREAKPOINT);
   }
 
   do_cleanups (old_chain);
@@ -3936,7 +3941,7 @@ detach_breakpoints (ptid_t ptid)
    *not* look at bl->pspace->aspace here.  */
 
 static int
-remove_breakpoint_1 (struct bp_location *bl, insertion_state_t is)
+remove_breakpoint_1 (struct bp_location *bl, enum remove_bp_reason reason)
 {
   int val;
 
@@ -4048,18 +4053,18 @@ remove_breakpoint_1 (struct bp_location *bl, insertion_state_t is)
 
       if (val)
 	return val;
-      bl->inserted = (is == mark_inserted);
+      bl->inserted = (reason == DETACH_BREAKPOINT);
     }
   else if (bl->loc_type == bp_loc_hardware_watchpoint)
     {
       gdb_assert (bl->owner->ops != NULL
 		  && bl->owner->ops->remove_location != NULL);
 
-      bl->inserted = (is == mark_inserted);
+      bl->inserted = (reason == DETACH_BREAKPOINT);
       bl->owner->ops->remove_location (bl);
 
       /* Failure to remove any of the hardware watchpoints comes here.  */
-      if ((is == mark_uninserted) && (bl->inserted))
+      if (reason == REMOVE_BREAKPOINT && bl->inserted)
 	warning (_("Could not remove hardware watchpoint %d."),
 		 bl->owner->number);
     }
@@ -4074,7 +4079,7 @@ remove_breakpoint_1 (struct bp_location *bl, insertion_state_t is)
       if (val)
 	return val;
 
-      bl->inserted = (is == mark_inserted);
+      bl->inserted = (reason == DETACH_BREAKPOINT);
     }
 
   return 0;
@@ -4097,7 +4102,7 @@ remove_breakpoint (struct bp_location *bl)
 
   switch_to_program_space_and_thread (bl->pspace);
 
-  ret = remove_breakpoint_1 (bl, mark_uninserted);
+  ret = remove_breakpoint_1 (bl, REMOVE_BREAKPOINT);
 
   do_cleanups (old_chain);
   return ret;
-- 
1.9.3

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 0/4] Fix PR gdb/19187 (process record over a fork causes internal error)
@ 2016-02-14 18:37 Pedro Alves
  2016-02-14 18:37 ` [PATCH 3/4] Plumb enum remove_bp_reason all the way to target_remove_breakpoint Pedro Alves
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Pedro Alves @ 2016-02-14 18:37 UTC (permalink / raw)
  To: gdb-patches

This series fixes:

 (gdb) record
 break marker2
 Breakpoint 2 at 0x40067a: file /home/pedro/gdb/mygit/src/gdb/testsuite/gdb.reverse/waitpid-reverse.c, line 30.
 (gdb) PASS: gdb.reverse/waitpid-reverse.exp: set breakpoint at marker2
 continue
 Continuing.
 /home/pedro/gdb/mygit/src/gdb/record-full.c:1720: internal-error: record_full_remove_breakpoint: removing unknown breakpoint
 A problem internal to GDB has been detected,
 further debugging may prove unreliable.
 Quit this debugging session? (y or n)
 KFAIL: gdb.reverse/waitpid-reverse.exp: continue to breakpoint: marker2 (GDB internal error) (PRMS: gdb/19187)

The problem is that the target side can't distinguish between deleting
a breakpoint and detaching a breakpoint.

Right after a fork is detected, we detach breakpoints from the child
(detach_breakpoints), which calls into target_remove_breakpoint with
inferior_ptid pointing at the child process, but leaves the breakpoint
marked inserted (in the parent).

Since record-full.c's target_remove_breakpoint implementation doesn't
know we're detaching a breakpoint, it removes the breakpoint from its
own breakpoint table.

Then when we later remove the breakpoint from the parent, we fail that
assertion, since the breakpoint is unexpectedly not found in the
record-full.c breakpoint table.

The first three patches pass down the reason for removing the
breakpoint all the way to the target.

Patch 4 then simply makes record-full.c not delete the breakpoint from
its breakpoint table when we're detaching the breakpoint from a fork
child.

Pedro Alves (4):
  Simplify remove_breakpoint interface
  Introduce 'enum remove_bp_reason'
  Plumb enum remove_bp_reason all the way to target_remove_breakpoint
  Fix PR gdb/19187 (process record over a fork causes internal error)

 gdb/break-catch-sig.c                         |  3 +-
 gdb/break-catch-syscall.c                     |  2 +-
 gdb/breakpoint.c                              | 70 +++++++++++++--------------
 gdb/breakpoint.h                              | 14 +++++-
 gdb/corelow.c                                 | 10 +++-
 gdb/exec.c                                    | 10 +++-
 gdb/mem-break.c                               |  3 +-
 gdb/record-btrace.c                           |  6 ++-
 gdb/record-full.c                             | 15 ++++--
 gdb/remote.c                                  |  5 +-
 gdb/target-debug.h                            |  2 +
 gdb/target-delegates.c                        | 10 ++--
 gdb/target.c                                  |  5 +-
 gdb/target.h                                  |  9 ++--
 gdb/testsuite/gdb.reverse/waitpid-reverse.exp |  4 +-
 15 files changed, 105 insertions(+), 63 deletions(-)

-- 
1.9.3

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 3/4] Plumb enum remove_bp_reason all the way to target_remove_breakpoint
  2016-02-14 18:37 [PATCH 0/4] Fix PR gdb/19187 (process record over a fork causes internal error) Pedro Alves
@ 2016-02-14 18:37 ` Pedro Alves
  2016-02-15  9:12   ` Yao Qi
  2016-02-14 18:37 ` [PATCH 1/4] Simplify remove_breakpoint interface Pedro Alves
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 8+ messages in thread
From: Pedro Alves @ 2016-02-14 18:37 UTC (permalink / raw)
  To: gdb-patches

So the target knows whether we're detaching breakpoints.
Nothing uses the parameter in this patch yet.

gdb/ChangeLog:
2016-02-14  Pedro Alves  <palves@redhat.com>

	* break-catch-sig.c (signal_catchpoint_remove_location): Adjust
	interface.
	* break-catch-syscall.c (remove_catch_syscall):
	* breakpoint.c (enum remove_bp_reason): Moved to breakpoint.h.
	(remove_breakpoint_1): Pass 'reason' down.
	(remove_catch_fork, remove_catch_vfork, remove_catch_solib)
	(remove_catch_exec, remove_watchpoint, remove_masked_watchpoint)
	(base_breakpoint_remove_location, bkpt_remove_location)
	(bkpt_probe_remove_location, bkpt_probe_remove_location): Adjust
	interface.
	* breakpoint.h (enum remove_bp_reason): Moved here from
	breakpoint.c.
	(struct breakpoint_ops) <remove_location>: Add 'reason' parameter.
	* corelow.c (core_remove_breakpoint): New function.
	(init_core_ops): Install it as to_remove_breakpoint method.
	* exec.c (exec_remove_breakpoint): New function.
	(init_exec_ops): Install it as to_remove_breakpoint method.
	* mem-break.c (memory_remove_breakpoint): Adjust interface.
	* record-btrace.c (record_btrace_remove_breakpoint): Adjust
	interface.
	* record-full.c (record_full_remove_breakpoint)
	(record_full_core_remove_breakpoint): Adjust interface.
	* remote.c (remote_remove_breakpoint): Adjust interface.
	* target-debug.h (target_debug_print_enum_remove_bp_reason): New
	macro.
	* target-delegates.c: Regenerate.
	* target.c (target_remove_breakpoint): Add 'reason' parameter.
	* target.h (struct target_ops) <to_remove_breakpoint>: Add
	'reason' parameter.
	(target_remove_breakpoint, memory_remove_breakpoint): Add 'reason'
	parameter.
---
 gdb/break-catch-sig.c     |  3 ++-
 gdb/break-catch-syscall.c |  2 +-
 gdb/breakpoint.c          | 47 +++++++++++++++++++----------------------------
 gdb/breakpoint.h          | 14 +++++++++++++-
 gdb/corelow.c             | 10 +++++++++-
 gdb/exec.c                | 10 +++++++++-
 gdb/mem-break.c           |  3 ++-
 gdb/record-btrace.c       |  6 ++++--
 gdb/record-full.c         |  8 +++++---
 gdb/remote.c              |  5 +++--
 gdb/target-debug.h        |  2 ++
 gdb/target-delegates.c    | 10 ++++++----
 gdb/target.c              |  5 +++--
 gdb/target.h              |  9 ++++++---
 14 files changed, 84 insertions(+), 50 deletions(-)

diff --git a/gdb/break-catch-sig.c b/gdb/break-catch-sig.c
index dcfae42..06ee44c 100644
--- a/gdb/break-catch-sig.c
+++ b/gdb/break-catch-sig.c
@@ -137,7 +137,8 @@ signal_catchpoint_insert_location (struct bp_location *bl)
    catchpoints.  */
 
 static int
-signal_catchpoint_remove_location (struct bp_location *bl)
+signal_catchpoint_remove_location (struct bp_location *bl,
+				   enum remove_bp_reason reason)
 {
   struct signal_catchpoint *c = (struct signal_catchpoint *) bl->owner;
   int i;
diff --git a/gdb/break-catch-syscall.c b/gdb/break-catch-syscall.c
index dbebdda..ec73a93 100644
--- a/gdb/break-catch-syscall.c
+++ b/gdb/break-catch-syscall.c
@@ -158,7 +158,7 @@ insert_catch_syscall (struct bp_location *bl)
    catchpoints.  */
 
 static int
-remove_catch_syscall (struct bp_location *bl)
+remove_catch_syscall (struct bp_location *bl, enum remove_bp_reason reason)
 {
   struct syscall_catchpoint *c = (struct syscall_catchpoint *) bl->owner;
   struct inferior *inf = current_inferior ();
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 9b37508..311f06e 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -194,18 +194,6 @@ static void commands_command (char *, int);
 
 static void condition_command (char *, int);
 
-/* Why are we removing the breakpoint from the target?  */
-
-enum remove_bp_reason
-{
-  /* A regular remove.  Remove the breakpoint and forget everything
-     about it.  */
-  REMOVE_BREAKPOINT,
-
-  /* Detach the breakpoints from a fork child.  */
-  DETACH_BREAKPOINT,
-};
-
 static int remove_breakpoint (struct bp_location *);
 static int remove_breakpoint_1 (struct bp_location *, enum remove_bp_reason);
 
@@ -3989,7 +3977,7 @@ remove_breakpoint_1 (struct bp_location *bl, enum remove_bp_reason reason)
 	      && !memory_validate_breakpoint (bl->gdbarch, &bl->target_info))
 	    val = 0;
 	  else
-	    val = bl->owner->ops->remove_location (bl);
+	    val = bl->owner->ops->remove_location (bl, reason);
 	}
       else
 	{
@@ -4007,7 +3995,8 @@ remove_breakpoint_1 (struct bp_location *bl, enum remove_bp_reason reason)
 					       &bl->overlay_target_info);
 		else
 		  target_remove_breakpoint (bl->gdbarch,
-					    &bl->overlay_target_info);
+					    &bl->overlay_target_info,
+					    reason);
 	      }
 	  /* Did we set a breakpoint at the VMA? 
 	     If so, we will have marked the breakpoint 'inserted'.  */
@@ -4023,7 +4012,7 @@ remove_breakpoint_1 (struct bp_location *bl, enum remove_bp_reason reason)
 		 wrong code with the saved shadow contents.  */
 	      if (bl->loc_type == bp_loc_hardware_breakpoint
 		  || section_is_mapped (bl->section))
-		val = bl->owner->ops->remove_location (bl);
+		val = bl->owner->ops->remove_location (bl, reason);
 	      else
 		val = 0;
 	    }
@@ -4061,7 +4050,7 @@ remove_breakpoint_1 (struct bp_location *bl, enum remove_bp_reason reason)
 		  && bl->owner->ops->remove_location != NULL);
 
       bl->inserted = (reason == DETACH_BREAKPOINT);
-      bl->owner->ops->remove_location (bl);
+      bl->owner->ops->remove_location (bl, reason);
 
       /* Failure to remove any of the hardware watchpoints comes here.  */
       if (reason == REMOVE_BREAKPOINT && bl->inserted)
@@ -4075,7 +4064,7 @@ remove_breakpoint_1 (struct bp_location *bl, enum remove_bp_reason reason)
       gdb_assert (bl->owner->ops != NULL
 		  && bl->owner->ops->remove_location != NULL);
 
-      val = bl->owner->ops->remove_location (bl);
+      val = bl->owner->ops->remove_location (bl, reason);
       if (val)
 	return val;
 
@@ -8086,7 +8075,7 @@ insert_catch_fork (struct bp_location *bl)
    catchpoints.  */
 
 static int
-remove_catch_fork (struct bp_location *bl)
+remove_catch_fork (struct bp_location *bl, enum remove_bp_reason reason)
 {
   return target_remove_fork_catchpoint (ptid_get_pid (inferior_ptid));
 }
@@ -8204,7 +8193,7 @@ insert_catch_vfork (struct bp_location *bl)
    catchpoints.  */
 
 static int
-remove_catch_vfork (struct bp_location *bl)
+remove_catch_vfork (struct bp_location *bl, enum remove_bp_reason reason)
 {
   return target_remove_vfork_catchpoint (ptid_get_pid (inferior_ptid));
 }
@@ -8347,7 +8336,7 @@ insert_catch_solib (struct bp_location *ignore)
 }
 
 static int
-remove_catch_solib (struct bp_location *ignore)
+remove_catch_solib (struct bp_location *ignore, enum remove_bp_reason reason)
 {
   return 0;
 }
@@ -8677,7 +8666,7 @@ insert_catch_exec (struct bp_location *bl)
 }
 
 static int
-remove_catch_exec (struct bp_location *bl)
+remove_catch_exec (struct bp_location *bl, enum remove_bp_reason reason)
 {
   return target_remove_exec_catchpoint (ptid_get_pid (inferior_ptid));
 }
@@ -10686,7 +10675,7 @@ insert_watchpoint (struct bp_location *bl)
 /* Implement the "remove" breakpoint_ops method for hardware watchpoints.  */
 
 static int
-remove_watchpoint (struct bp_location *bl)
+remove_watchpoint (struct bp_location *bl, enum remove_bp_reason reason)
 {
   struct watchpoint *w = (struct watchpoint *) bl->owner;
   int length = w->exact ? 1 : bl->length;
@@ -10941,7 +10930,7 @@ insert_masked_watchpoint (struct bp_location *bl)
    masked hardware watchpoints.  */
 
 static int
-remove_masked_watchpoint (struct bp_location *bl)
+remove_masked_watchpoint (struct bp_location *bl, enum remove_bp_reason reason)
 {
   struct watchpoint *w = (struct watchpoint *) bl->owner;
 
@@ -12934,7 +12923,8 @@ base_breakpoint_insert_location (struct bp_location *bl)
 }
 
 static int
-base_breakpoint_remove_location (struct bp_location *bl)
+base_breakpoint_remove_location (struct bp_location *bl,
+				 enum remove_bp_reason reason)
 {
   internal_error_pure_virtual_called ();
 }
@@ -13096,12 +13086,12 @@ bkpt_insert_location (struct bp_location *bl)
 }
 
 static int
-bkpt_remove_location (struct bp_location *bl)
+bkpt_remove_location (struct bp_location *bl, enum remove_bp_reason reason)
 {
   if (bl->loc_type == bp_loc_hardware_breakpoint)
     return target_remove_hw_breakpoint (bl->gdbarch, &bl->target_info);
   else
-    return target_remove_breakpoint (bl->gdbarch, &bl->target_info);
+    return target_remove_breakpoint (bl->gdbarch, &bl->target_info, reason);
 }
 
 static int
@@ -13444,7 +13434,8 @@ bkpt_probe_insert_location (struct bp_location *bl)
 }
 
 static int
-bkpt_probe_remove_location (struct bp_location *bl)
+bkpt_probe_remove_location (struct bp_location *bl,
+			    enum remove_bp_reason reason)
 {
   /* Let's clear the semaphore before removing the location.  */
   if (bl->probe.probe->pops->clear_semaphore != NULL)
@@ -13452,7 +13443,7 @@ bkpt_probe_remove_location (struct bp_location *bl)
 					    bl->probe.objfile,
 					    bl->gdbarch);
 
-  return bkpt_remove_location (bl);
+  return bkpt_remove_location (bl, reason);
 }
 
 static void
diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
index 054eab4d..c7d7462 100644
--- a/gdb/breakpoint.h
+++ b/gdb/breakpoint.h
@@ -39,6 +39,18 @@ struct linespec_result;
 struct linespec_sals;
 struct event_location;
 
+/* Why are we removing the breakpoint from the target?  */
+
+enum remove_bp_reason
+{
+  /* A regular remove.  Remove the breakpoint and forget everything
+     about it.  */
+  REMOVE_BREAKPOINT,
+
+  /* Detach the breakpoints from a fork child.  */
+  DETACH_BREAKPOINT,
+};
+
 /* This is the maximum number of bytes a breakpoint instruction can
    take.  Feel free to increase it.  It's just used in a few places to
    size arrays that should be independent of the target
@@ -519,7 +531,7 @@ struct breakpoint_ops
      with the "insert" method above.  Return 0 for success, 1 if the
      breakpoint, watchpoint or catchpoint type is not supported,
      -1 for failure.  */
-  int (*remove_location) (struct bp_location *);
+  int (*remove_location) (struct bp_location *, enum remove_bp_reason reason);
 
   /* Return true if it the target has stopped due to hitting
      breakpoint location BL.  This function does not check if we
diff --git a/gdb/corelow.c b/gdb/corelow.c
index 224719e..e8c9cc8 100644
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -920,6 +920,14 @@ ignore (struct target_ops *ops, struct gdbarch *gdbarch,
   return 0;
 }
 
+static int
+core_remove_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
+			struct bp_target_info *bp_tgt,
+			enum remove_bp_reason reason)
+{
+  return 0;
+}
+
 
 /* Okay, let's be honest: threads gleaned from a core file aren't
    exactly lively, are they?  On the other hand, if we don't claim
@@ -1043,7 +1051,7 @@ init_core_ops (void)
   core_ops.to_xfer_partial = core_xfer_partial;
   core_ops.to_files_info = core_files_info;
   core_ops.to_insert_breakpoint = ignore;
-  core_ops.to_remove_breakpoint = ignore;
+  core_ops.to_remove_breakpoint = core_remove_breakpoint;
   core_ops.to_thread_alive = core_thread_alive;
   core_ops.to_read_description = core_read_description;
   core_ops.to_pid_to_str = core_pid_to_str;
diff --git a/gdb/exec.c b/gdb/exec.c
index 23c89c2..4dba3e1 100644
--- a/gdb/exec.c
+++ b/gdb/exec.c
@@ -1006,6 +1006,14 @@ ignore (struct target_ops *ops, struct gdbarch *gdbarch,
 }
 
 static int
+exec_remove_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
+			struct bp_target_info *bp_tgt,
+			enum remove_bp_reason reason)
+{
+  return 0;
+}
+
+static int
 exec_has_memory (struct target_ops *ops)
 {
   /* We can provide memory if we have any file/target sections to read
@@ -1036,7 +1044,7 @@ Specify the filename of the executable file.";
   exec_ops.to_get_section_table = exec_get_section_table;
   exec_ops.to_files_info = exec_files_info;
   exec_ops.to_insert_breakpoint = ignore;
-  exec_ops.to_remove_breakpoint = ignore;
+  exec_ops.to_remove_breakpoint = exec_remove_breakpoint;
   exec_ops.to_stratum = file_stratum;
   exec_ops.to_has_memory = exec_has_memory;
   exec_ops.to_make_corefile_notes = exec_make_note_section;
diff --git a/gdb/mem-break.c b/gdb/mem-break.c
index 9bb4c45..803f62b 100644
--- a/gdb/mem-break.c
+++ b/gdb/mem-break.c
@@ -93,7 +93,8 @@ memory_insert_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
 
 int
 memory_remove_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
-			  struct bp_target_info *bp_tgt)
+			  struct bp_target_info *bp_tgt,
+			  enum remove_bp_reason reason)
 {
   return gdbarch_memory_remove_breakpoint (gdbarch, bp_tgt);
 }
diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index 77b5180..6a5ffa4 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -1406,7 +1406,8 @@ record_btrace_insert_breakpoint (struct target_ops *ops,
 static int
 record_btrace_remove_breakpoint (struct target_ops *ops,
 				 struct gdbarch *gdbarch,
-				 struct bp_target_info *bp_tgt)
+				 struct bp_target_info *bp_tgt,
+				 enum remove_bp_reason reason)
 {
   const char *old;
   int ret;
@@ -1419,7 +1420,8 @@ record_btrace_remove_breakpoint (struct target_ops *ops,
   ret = 0;
   TRY
     {
-      ret = ops->beneath->to_remove_breakpoint (ops->beneath, gdbarch, bp_tgt);
+      ret = ops->beneath->to_remove_breakpoint (ops->beneath, gdbarch, bp_tgt,
+						reason);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
diff --git a/gdb/record-full.c b/gdb/record-full.c
index f6023bf..418a346 100644
--- a/gdb/record-full.c
+++ b/gdb/record-full.c
@@ -1684,7 +1684,8 @@ record_full_insert_breakpoint (struct target_ops *ops,
 static int
 record_full_remove_breakpoint (struct target_ops *ops,
 			       struct gdbarch *gdbarch,
-			       struct bp_target_info *bp_tgt)
+			       struct bp_target_info *bp_tgt,
+			       enum remove_bp_reason reason)
 {
   struct record_full_breakpoint *bp;
   int ix;
@@ -1704,7 +1705,7 @@ record_full_remove_breakpoint (struct target_ops *ops,
 
 	      old_cleanups = record_full_gdb_operation_disable_set ();
 	      ret = ops->beneath->to_remove_breakpoint (ops->beneath, gdbarch,
-							bp_tgt);
+							bp_tgt, reason);
 	      do_cleanups (old_cleanups);
 
 	      if (ret != 0)
@@ -2171,7 +2172,8 @@ record_full_core_insert_breakpoint (struct target_ops *ops,
 static int
 record_full_core_remove_breakpoint (struct target_ops *ops,
 				    struct gdbarch *gdbarch,
-				    struct bp_target_info *bp_tgt)
+				    struct bp_target_info *bp_tgt,
+				    enum remove_bp_reason reason)
 {
   return 0;
 }
diff --git a/gdb/remote.c b/gdb/remote.c
index 6d56f19..404a5c6 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -9339,7 +9339,8 @@ Target doesn't support breakpoints that have target side commands."));
 static int
 remote_remove_breakpoint (struct target_ops *ops,
 			  struct gdbarch *gdbarch,
-			  struct bp_target_info *bp_tgt)
+			  struct bp_target_info *bp_tgt,
+			  enum remove_bp_reason reason)
 {
   CORE_ADDR addr = bp_tgt->placed_address;
   struct remote_state *rs = get_remote_state ();
@@ -9368,7 +9369,7 @@ remote_remove_breakpoint (struct target_ops *ops,
       return (rs->buf[0] == 'E');
     }
 
-  return memory_remove_breakpoint (ops, gdbarch, bp_tgt);
+  return memory_remove_breakpoint (ops, gdbarch, bp_tgt, reason);
 }
 
 static enum Z_packet_type
diff --git a/gdb/target-debug.h b/gdb/target-debug.h
index 5f44d11..ef7e14d 100644
--- a/gdb/target-debug.h
+++ b/gdb/target-debug.h
@@ -158,6 +158,8 @@
   target_debug_do_print (plongest (X))
 #define target_debug_print_struct_inferior_p(X)	\
   target_debug_do_print (host_address_to_string (X))
+#define target_debug_print_enum_remove_bp_reason(X) \
+  target_debug_do_print (plongest (X))
 
 static void
 target_debug_print_struct_target_waitstatus_p (struct target_waitstatus *status)
diff --git a/gdb/target-delegates.c b/gdb/target-delegates.c
index d23bc75..e21746f 100644
--- a/gdb/target-delegates.c
+++ b/gdb/target-delegates.c
@@ -262,24 +262,26 @@ debug_insert_breakpoint (struct target_ops *self, struct gdbarch *arg1, struct b
 }
 
 static int
-delegate_remove_breakpoint (struct target_ops *self, struct gdbarch *arg1, struct bp_target_info *arg2)
+delegate_remove_breakpoint (struct target_ops *self, struct gdbarch *arg1, struct bp_target_info *arg2, enum remove_bp_reason arg3)
 {
   self = self->beneath;
-  return self->to_remove_breakpoint (self, arg1, arg2);
+  return self->to_remove_breakpoint (self, arg1, arg2, arg3);
 }
 
 static int
-debug_remove_breakpoint (struct target_ops *self, struct gdbarch *arg1, struct bp_target_info *arg2)
+debug_remove_breakpoint (struct target_ops *self, struct gdbarch *arg1, struct bp_target_info *arg2, enum remove_bp_reason arg3)
 {
   int result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->to_remove_breakpoint (...)\n", debug_target.to_shortname);
-  result = debug_target.to_remove_breakpoint (&debug_target, arg1, arg2);
+  result = debug_target.to_remove_breakpoint (&debug_target, arg1, arg2, arg3);
   fprintf_unfiltered (gdb_stdlog, "<- %s->to_remove_breakpoint (", debug_target.to_shortname);
   target_debug_print_struct_target_ops_p (&debug_target);
   fputs_unfiltered (", ", gdb_stdlog);
   target_debug_print_struct_gdbarch_p (arg1);
   fputs_unfiltered (", ", gdb_stdlog);
   target_debug_print_struct_bp_target_info_p (arg2);
+  fputs_unfiltered (", ", gdb_stdlog);
+  target_debug_print_enum_remove_bp_reason (arg3);
   fputs_unfiltered (") = ", gdb_stdlog);
   target_debug_print_int (result);
   fputs_unfiltered ("\n", gdb_stdlog);
diff --git a/gdb/target.c b/gdb/target.c
index ac66a3a..a0d5937 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -2081,7 +2081,8 @@ target_insert_breakpoint (struct gdbarch *gdbarch,
 
 int
 target_remove_breakpoint (struct gdbarch *gdbarch,
-			  struct bp_target_info *bp_tgt)
+			  struct bp_target_info *bp_tgt,
+			  enum remove_bp_reason reason)
 {
   /* This is kind of a weird case to handle, but the permission might
      have been changed after breakpoints were inserted - in which case
@@ -2094,7 +2095,7 @@ target_remove_breakpoint (struct gdbarch *gdbarch,
     }
 
   return current_target.to_remove_breakpoint (&current_target,
-					      gdbarch, bp_tgt);
+					      gdbarch, bp_tgt, reason);
 }
 
 static void
diff --git a/gdb/target.h b/gdb/target.h
index e1419a9..7c8513a 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -478,7 +478,8 @@ struct target_ops
 				 struct bp_target_info *)
       TARGET_DEFAULT_FUNC (memory_insert_breakpoint);
     int (*to_remove_breakpoint) (struct target_ops *, struct gdbarch *,
-				 struct bp_target_info *)
+				 struct bp_target_info *,
+				 enum remove_bp_reason)
       TARGET_DEFAULT_FUNC (memory_remove_breakpoint);
 
     /* Returns true if the target stopped because it executed a
@@ -1496,7 +1497,8 @@ extern int target_insert_breakpoint (struct gdbarch *gdbarch,
    machine.  Result is 0 for success, non-zero for error.  */
 
 extern int target_remove_breakpoint (struct gdbarch *gdbarch,
-				     struct bp_target_info *bp_tgt);
+				     struct bp_target_info *bp_tgt,
+				     enum remove_bp_reason reason);
 
 /* Returns true if the terminal settings of the inferior are in
    effect.  */
@@ -2356,7 +2358,8 @@ extern struct target_section_table *target_get_section_table
 /* From mem-break.c */
 
 extern int memory_remove_breakpoint (struct target_ops *, struct gdbarch *,
-				     struct bp_target_info *);
+				     struct bp_target_info *,
+				     enum remove_bp_reason);
 
 extern int memory_insert_breakpoint (struct target_ops *, struct gdbarch *,
 				     struct bp_target_info *);
-- 
1.9.3

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/4] Simplify remove_breakpoint interface
  2016-02-14 18:37 [PATCH 0/4] Fix PR gdb/19187 (process record over a fork causes internal error) Pedro Alves
  2016-02-14 18:37 ` [PATCH 3/4] Plumb enum remove_bp_reason all the way to target_remove_breakpoint Pedro Alves
@ 2016-02-14 18:37 ` Pedro Alves
  2016-02-14 18:37 ` [PATCH 2/4] Introduce 'enum remove_bp_reason' Pedro Alves
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Pedro Alves @ 2016-02-14 18:37 UTC (permalink / raw)
  To: gdb-patches

All callers pass mark_uninserted, so there's no need for the 'is'
parameter.

gdb/ChangeLog:
2016-02-14  Pedro Alves  <palves@redhat.com>

	* breakpoint.c (remove_breakpoint): Remove 'is' parameter and
	always pass mark_uninserted to remove_breakpoint_1.
	(insert_breakpoint_locations, remove_breakpoints)
	(remove_breakpoints_pid, update_global_location_list): Update
	callers.
---
 gdb/breakpoint.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index f99a7ab..05da8ed 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -201,7 +201,7 @@ typedef enum
   }
 insertion_state_t;
 
-static int remove_breakpoint (struct bp_location *, insertion_state_t);
+static int remove_breakpoint (struct bp_location *);
 static int remove_breakpoint_1 (struct bp_location *, insertion_state_t);
 
 static enum print_stop_action print_bp_stop_message (bpstat bs);
@@ -3182,7 +3182,7 @@ insert_breakpoint_locations (void)
 	{
 	  for (loc = bpt->loc; loc; loc = loc->next)
 	    if (loc->inserted)
-	      remove_breakpoint (loc, mark_uninserted);
+	      remove_breakpoint (loc);
 
 	  hw_breakpoint_error = 1;
 	  fprintf_unfiltered (tmp_error_stream,
@@ -3222,7 +3222,7 @@ remove_breakpoints (void)
   ALL_BP_LOCATIONS (bl, blp_tmp)
   {
     if (bl->inserted && !is_tracepoint (bl->owner))
-      val |= remove_breakpoint (bl, mark_uninserted);
+      val |= remove_breakpoint (bl);
   }
   return val;
 }
@@ -3267,7 +3267,7 @@ remove_breakpoints_pid (int pid)
 
     if (bl->inserted && !bl->target_info.persist)
       {
-	val = remove_breakpoint (bl, mark_uninserted);
+	val = remove_breakpoint (bl);
 	if (val != 0)
 	  return val;
       }
@@ -4081,7 +4081,7 @@ remove_breakpoint_1 (struct bp_location *bl, insertion_state_t is)
 }
 
 static int
-remove_breakpoint (struct bp_location *bl, insertion_state_t is)
+remove_breakpoint (struct bp_location *bl)
 {
   int ret;
   struct cleanup *old_chain;
@@ -4097,7 +4097,7 @@ remove_breakpoint (struct bp_location *bl, insertion_state_t is)
 
   switch_to_program_space_and_thread (bl->pspace);
 
-  ret = remove_breakpoint_1 (bl, is);
+  ret = remove_breakpoint_1 (bl, mark_uninserted);
 
   do_cleanups (old_chain);
   return ret;
@@ -12572,7 +12572,7 @@ update_global_location_list (enum ugll_insert_mode insert_mode)
 
 	  if (!keep_in_target)
 	    {
-	      if (remove_breakpoint (old_loc, mark_uninserted))
+	      if (remove_breakpoint (old_loc))
 		{
 		  /* This is just about all we can do.  We could keep
 		     this location on the global list, and try to
-- 
1.9.3

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 4/4] Fix PR gdb/19187 (process record over a fork causes internal error)
  2016-02-14 18:37 [PATCH 0/4] Fix PR gdb/19187 (process record over a fork causes internal error) Pedro Alves
                   ` (2 preceding siblings ...)
  2016-02-14 18:37 ` [PATCH 2/4] Introduce 'enum remove_bp_reason' Pedro Alves
@ 2016-02-14 18:44 ` Pedro Alves
  2016-08-10 22:11 ` [PATCH 0/4] " Pedro Alves
  4 siblings, 0 replies; 8+ messages in thread
From: Pedro Alves @ 2016-02-14 18:44 UTC (permalink / raw)
  To: gdb-patches

Right after a fork is detected, we detach breakpoints from the child
(detach_breakpoints), which calls into target_remove_breakpoint with
inferior_ptid pointing at the child process, but leaves the breakpoint
marked inserted (in the parent).

The problem is that record-full.c always deletes all knowledge of the
breakpoint.  Then when we later really delete the breakpoint from the
parent, we fail the assertion, since the breakpoint is unexpectedly
not found in the record-full.c breakpoint table.

The fix is simply to not forget about the breakpoint if we're
detaching it from a fork child.

gdb/ChangeLog:
2016-02-14  Pedro Alves  <palves@redhat.com>

	PR gdb/19187
	* record-full.c (record_full_remove_breakpoint): Don't remove the
	breakpoint from the record_full_breakpoints VEC if we're detaching
	the breakpoint from a fork child.

gdb/testsuite/ChangeLog:
2016-02-14  Pedro Alves  <palves@redhat.com>

	PR gdb/19187
	* gdb.reverse/waitpid-reverse.exp: Add comment and remove
	setup_kfails.
---
 gdb/record-full.c                             | 7 +++++--
 gdb/testsuite/gdb.reverse/waitpid-reverse.exp | 4 ++--
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/gdb/record-full.c b/gdb/record-full.c
index 418a346..e325869 100644
--- a/gdb/record-full.c
+++ b/gdb/record-full.c
@@ -1712,8 +1712,11 @@ record_full_remove_breakpoint (struct target_ops *ops,
 		return ret;
 	    }
 
-	  VEC_unordered_remove (record_full_breakpoint_p,
-				record_full_breakpoints, ix);
+	  if (reason == REMOVE_BREAKPOINT)
+	    {
+	      VEC_unordered_remove (record_full_breakpoint_p,
+				    record_full_breakpoints, ix);
+	    }
 	  return 0;
 	}
     }
diff --git a/gdb/testsuite/gdb.reverse/waitpid-reverse.exp b/gdb/testsuite/gdb.reverse/waitpid-reverse.exp
index d583953..e8a1690 100644
--- a/gdb/testsuite/gdb.reverse/waitpid-reverse.exp
+++ b/gdb/testsuite/gdb.reverse/waitpid-reverse.exp
@@ -18,6 +18,8 @@
 #
 # This test tests waitpid syscall for reverse execution.
 #
+# Also serves as regression test for gdb/19187 (recording across a
+# fork).
 
 if ![supports_reverse] {
     return
@@ -40,14 +42,12 @@ gdb_test "break marker2" \
     "Breakpoint $decimal at $hex: file .*$srcfile, line $decimal.*" \
     "set breakpoint at marker2"
 
-setup_kfail "gdb/19187" *-*-*
 gdb_continue_to_breakpoint "marker2" ".*$srcfile:.*"
 
 gdb_test "break marker1" \
     "Breakpoint $decimal at $hex: file .*$srcfile, line $decimal.*" \
     "set breakpoint at marker1"
 
-setup_kfail "gdb/19187" *-*-*
 gdb_test "reverse-continue" ".*$srcfile:$decimal.*" "reverse to marker1"
 
 # If the variable was recorded properly on syscall, the old contents (-1)
-- 
1.9.3

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 3/4] Plumb enum remove_bp_reason all the way to target_remove_breakpoint
  2016-02-14 18:37 ` [PATCH 3/4] Plumb enum remove_bp_reason all the way to target_remove_breakpoint Pedro Alves
@ 2016-02-15  9:12   ` Yao Qi
  2016-02-15 14:41     ` Pedro Alves
  0 siblings, 1 reply; 8+ messages in thread
From: Yao Qi @ 2016-02-15  9:12 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

Pedro Alves <palves@redhat.com> writes:

Hi Pedro,

> So the target knows whether we're detaching breakpoints.
> Nothing uses the parameter in this patch yet.
>
> gdb/ChangeLog:
> 2016-02-14  Pedro Alves  <palves@redhat.com>
>
> 	* break-catch-sig.c (signal_catchpoint_remove_location): Adjust
> 	interface.
> 	* break-catch-syscall.c (remove_catch_syscall):
> 	* breakpoint.c (enum remove_bp_reason): Moved to breakpoint.h.
> 	(remove_breakpoint_1): Pass 'reason' down.
> 	(remove_catch_fork, remove_catch_vfork, remove_catch_solib)
> 	(remove_catch_exec, remove_watchpoint, remove_masked_watchpoint)
> 	(base_breakpoint_remove_location, bkpt_remove_location)
> 	(bkpt_probe_remove_location, bkpt_probe_remove_location): Adjust
> 	interface.
> 	* breakpoint.h (enum remove_bp_reason): Moved here from
> 	breakpoint.c.
> 	(struct breakpoint_ops) <remove_location>: Add 'reason' parameter.
> 	* corelow.c (core_remove_breakpoint): New function.
> 	(init_core_ops): Install it as to_remove_breakpoint method.
> 	* exec.c (exec_remove_breakpoint): New function.
> 	(init_exec_ops): Install it as to_remove_breakpoint method.
> 	* mem-break.c (memory_remove_breakpoint): Adjust interface.
> 	* record-btrace.c (record_btrace_remove_breakpoint): Adjust
> 	interface.
> 	* record-full.c (record_full_remove_breakpoint)
> 	(record_full_core_remove_breakpoint): Adjust interface.
> 	* remote.c (remote_remove_breakpoint): Adjust interface.
> 	* target-debug.h (target_debug_print_enum_remove_bp_reason): New
> 	macro.
> 	* target-delegates.c: Regenerate.
> 	* target.c (target_remove_breakpoint): Add 'reason' parameter.
> 	* target.h (struct target_ops) <to_remove_breakpoint>: Add
> 	'reason' parameter.
> 	(target_remove_breakpoint, memory_remove_breakpoint): Add 'reason'
> 	parameter.

We also need to add 'reason' in m32r_remove_breakpoint,
mips_remove_breakpoint and procfs_remove_breakpoint, otherwise the patch
breaks the all-targets build.

This patch series look good to me.

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 3/4] Plumb enum remove_bp_reason all the way to target_remove_breakpoint
  2016-02-15  9:12   ` Yao Qi
@ 2016-02-15 14:41     ` Pedro Alves
  0 siblings, 0 replies; 8+ messages in thread
From: Pedro Alves @ 2016-02-15 14:41 UTC (permalink / raw)
  To: Yao Qi; +Cc: gdb-patches

On 02/15/2016 09:12 AM, Yao Qi wrote:

> We also need to add 'reason' in m32r_remove_breakpoint,
> mips_remove_breakpoint and procfs_remove_breakpoint, otherwise the patch
> breaks the all-targets build.
> 
> This patch series look good to me.

Indeed.  Thanks for noticing.  I had a mental note to go over those, but
then lost it before posting...  :-)

Here's the updated patch.  I also added the missing comments to the
new functions in exec.c and corelow.c.

[PATCH] Plumb enum remove_bp_reason all the way to target_remove_breakpoint

So the target knows whether we're detaching breakpoints.
Nothing uses the parameter in this patch yet.

gdb/ChangeLog:
2016-02-15  Pedro Alves  <palves@redhat.com>

	* break-catch-sig.c (signal_catchpoint_remove_location): Adjust
	interface.
	* break-catch-syscall.c (remove_catch_syscall):
	* breakpoint.c (enum remove_bp_reason): Moved to breakpoint.h.
	(remove_breakpoint_1): Pass 'reason' down.
	(remove_catch_fork, remove_catch_vfork, remove_catch_solib)
	(remove_catch_exec, remove_watchpoint, remove_masked_watchpoint)
	(base_breakpoint_remove_location, bkpt_remove_location)
	(bkpt_probe_remove_location, bkpt_probe_remove_location): Adjust
	interface.
	* breakpoint.h (enum remove_bp_reason): Moved here from
	breakpoint.c.
	(struct breakpoint_ops) <remove_location>: Add 'reason' parameter.
	* corelow.c (core_remove_breakpoint): New function.
	(init_core_ops): Install it as to_remove_breakpoint method.
	* exec.c (exec_remove_breakpoint): New function.
	(init_exec_ops): Install it as to_remove_breakpoint method.
	* mem-break.c (memory_remove_breakpoint): Adjust interface.
	* record-btrace.c (record_btrace_remove_breakpoint): Adjust
	interface.
	* record-full.c (record_full_remove_breakpoint)
	(record_full_core_remove_breakpoint): Adjust interface.
	* remote-m32r.c (m32r_remove_breakpoint): Adjust interface.
	* remote-mips.c (mips_remove_breakpoint): Adjust interface.
	* remote.c (remote_remove_breakpoint): Adjust interface.
	* target-debug.h (target_debug_print_enum_remove_bp_reason): New
	macro.
	* target-delegates.c: Regenerate.
	* target.c (target_remove_breakpoint): Add 'reason' parameter.
	* target.h (struct target_ops) <to_remove_breakpoint>: Add
	'reason' parameter.
	(target_remove_breakpoint, memory_remove_breakpoint): Add 'reason'
	parameter.
---
 gdb/break-catch-sig.c     |  3 ++-
 gdb/break-catch-syscall.c |  2 +-
 gdb/breakpoint.c          | 47 +++++++++++++++++++----------------------------
 gdb/breakpoint.h          | 14 +++++++++++++-
 gdb/corelow.c             | 12 +++++++++++-
 gdb/exec.c                | 12 +++++++++++-
 gdb/mem-break.c           |  3 ++-
 gdb/nto-procfs.c          |  3 ++-
 gdb/record-btrace.c       |  6 ++++--
 gdb/record-full.c         |  8 +++++---
 gdb/remote-m32r-sdi.c     |  3 ++-
 gdb/remote-mips.c         |  5 +++--
 gdb/remote.c              |  5 +++--
 gdb/target-debug.h        |  2 ++
 gdb/target-delegates.c    | 10 ++++++----
 gdb/target.c              |  5 +++--
 gdb/target.h              |  9 ++++++---
 17 files changed, 95 insertions(+), 54 deletions(-)

diff --git a/gdb/break-catch-sig.c b/gdb/break-catch-sig.c
index dcfae42..06ee44c 100644
--- a/gdb/break-catch-sig.c
+++ b/gdb/break-catch-sig.c
@@ -137,7 +137,8 @@ signal_catchpoint_insert_location (struct bp_location *bl)
    catchpoints.  */
 
 static int
-signal_catchpoint_remove_location (struct bp_location *bl)
+signal_catchpoint_remove_location (struct bp_location *bl,
+				   enum remove_bp_reason reason)
 {
   struct signal_catchpoint *c = (struct signal_catchpoint *) bl->owner;
   int i;
diff --git a/gdb/break-catch-syscall.c b/gdb/break-catch-syscall.c
index dbebdda..ec73a93 100644
--- a/gdb/break-catch-syscall.c
+++ b/gdb/break-catch-syscall.c
@@ -158,7 +158,7 @@ insert_catch_syscall (struct bp_location *bl)
    catchpoints.  */
 
 static int
-remove_catch_syscall (struct bp_location *bl)
+remove_catch_syscall (struct bp_location *bl, enum remove_bp_reason reason)
 {
   struct syscall_catchpoint *c = (struct syscall_catchpoint *) bl->owner;
   struct inferior *inf = current_inferior ();
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 9b37508..311f06e 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -194,18 +194,6 @@ static void commands_command (char *, int);
 
 static void condition_command (char *, int);
 
-/* Why are we removing the breakpoint from the target?  */
-
-enum remove_bp_reason
-{
-  /* A regular remove.  Remove the breakpoint and forget everything
-     about it.  */
-  REMOVE_BREAKPOINT,
-
-  /* Detach the breakpoints from a fork child.  */
-  DETACH_BREAKPOINT,
-};
-
 static int remove_breakpoint (struct bp_location *);
 static int remove_breakpoint_1 (struct bp_location *, enum remove_bp_reason);
 
@@ -3989,7 +3977,7 @@ remove_breakpoint_1 (struct bp_location *bl, enum remove_bp_reason reason)
 	      && !memory_validate_breakpoint (bl->gdbarch, &bl->target_info))
 	    val = 0;
 	  else
-	    val = bl->owner->ops->remove_location (bl);
+	    val = bl->owner->ops->remove_location (bl, reason);
 	}
       else
 	{
@@ -4007,7 +3995,8 @@ remove_breakpoint_1 (struct bp_location *bl, enum remove_bp_reason reason)
 					       &bl->overlay_target_info);
 		else
 		  target_remove_breakpoint (bl->gdbarch,
-					    &bl->overlay_target_info);
+					    &bl->overlay_target_info,
+					    reason);
 	      }
 	  /* Did we set a breakpoint at the VMA? 
 	     If so, we will have marked the breakpoint 'inserted'.  */
@@ -4023,7 +4012,7 @@ remove_breakpoint_1 (struct bp_location *bl, enum remove_bp_reason reason)
 		 wrong code with the saved shadow contents.  */
 	      if (bl->loc_type == bp_loc_hardware_breakpoint
 		  || section_is_mapped (bl->section))
-		val = bl->owner->ops->remove_location (bl);
+		val = bl->owner->ops->remove_location (bl, reason);
 	      else
 		val = 0;
 	    }
@@ -4061,7 +4050,7 @@ remove_breakpoint_1 (struct bp_location *bl, enum remove_bp_reason reason)
 		  && bl->owner->ops->remove_location != NULL);
 
       bl->inserted = (reason == DETACH_BREAKPOINT);
-      bl->owner->ops->remove_location (bl);
+      bl->owner->ops->remove_location (bl, reason);
 
       /* Failure to remove any of the hardware watchpoints comes here.  */
       if (reason == REMOVE_BREAKPOINT && bl->inserted)
@@ -4075,7 +4064,7 @@ remove_breakpoint_1 (struct bp_location *bl, enum remove_bp_reason reason)
       gdb_assert (bl->owner->ops != NULL
 		  && bl->owner->ops->remove_location != NULL);
 
-      val = bl->owner->ops->remove_location (bl);
+      val = bl->owner->ops->remove_location (bl, reason);
       if (val)
 	return val;
 
@@ -8086,7 +8075,7 @@ insert_catch_fork (struct bp_location *bl)
    catchpoints.  */
 
 static int
-remove_catch_fork (struct bp_location *bl)
+remove_catch_fork (struct bp_location *bl, enum remove_bp_reason reason)
 {
   return target_remove_fork_catchpoint (ptid_get_pid (inferior_ptid));
 }
@@ -8204,7 +8193,7 @@ insert_catch_vfork (struct bp_location *bl)
    catchpoints.  */
 
 static int
-remove_catch_vfork (struct bp_location *bl)
+remove_catch_vfork (struct bp_location *bl, enum remove_bp_reason reason)
 {
   return target_remove_vfork_catchpoint (ptid_get_pid (inferior_ptid));
 }
@@ -8347,7 +8336,7 @@ insert_catch_solib (struct bp_location *ignore)
 }
 
 static int
-remove_catch_solib (struct bp_location *ignore)
+remove_catch_solib (struct bp_location *ignore, enum remove_bp_reason reason)
 {
   return 0;
 }
@@ -8677,7 +8666,7 @@ insert_catch_exec (struct bp_location *bl)
 }
 
 static int
-remove_catch_exec (struct bp_location *bl)
+remove_catch_exec (struct bp_location *bl, enum remove_bp_reason reason)
 {
   return target_remove_exec_catchpoint (ptid_get_pid (inferior_ptid));
 }
@@ -10686,7 +10675,7 @@ insert_watchpoint (struct bp_location *bl)
 /* Implement the "remove" breakpoint_ops method for hardware watchpoints.  */
 
 static int
-remove_watchpoint (struct bp_location *bl)
+remove_watchpoint (struct bp_location *bl, enum remove_bp_reason reason)
 {
   struct watchpoint *w = (struct watchpoint *) bl->owner;
   int length = w->exact ? 1 : bl->length;
@@ -10941,7 +10930,7 @@ insert_masked_watchpoint (struct bp_location *bl)
    masked hardware watchpoints.  */
 
 static int
-remove_masked_watchpoint (struct bp_location *bl)
+remove_masked_watchpoint (struct bp_location *bl, enum remove_bp_reason reason)
 {
   struct watchpoint *w = (struct watchpoint *) bl->owner;
 
@@ -12934,7 +12923,8 @@ base_breakpoint_insert_location (struct bp_location *bl)
 }
 
 static int
-base_breakpoint_remove_location (struct bp_location *bl)
+base_breakpoint_remove_location (struct bp_location *bl,
+				 enum remove_bp_reason reason)
 {
   internal_error_pure_virtual_called ();
 }
@@ -13096,12 +13086,12 @@ bkpt_insert_location (struct bp_location *bl)
 }
 
 static int
-bkpt_remove_location (struct bp_location *bl)
+bkpt_remove_location (struct bp_location *bl, enum remove_bp_reason reason)
 {
   if (bl->loc_type == bp_loc_hardware_breakpoint)
     return target_remove_hw_breakpoint (bl->gdbarch, &bl->target_info);
   else
-    return target_remove_breakpoint (bl->gdbarch, &bl->target_info);
+    return target_remove_breakpoint (bl->gdbarch, &bl->target_info, reason);
 }
 
 static int
@@ -13444,7 +13434,8 @@ bkpt_probe_insert_location (struct bp_location *bl)
 }
 
 static int
-bkpt_probe_remove_location (struct bp_location *bl)
+bkpt_probe_remove_location (struct bp_location *bl,
+			    enum remove_bp_reason reason)
 {
   /* Let's clear the semaphore before removing the location.  */
   if (bl->probe.probe->pops->clear_semaphore != NULL)
@@ -13452,7 +13443,7 @@ bkpt_probe_remove_location (struct bp_location *bl)
 					    bl->probe.objfile,
 					    bl->gdbarch);
 
-  return bkpt_remove_location (bl);
+  return bkpt_remove_location (bl, reason);
 }
 
 static void
diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
index 054eab4d..c7d7462 100644
--- a/gdb/breakpoint.h
+++ b/gdb/breakpoint.h
@@ -39,6 +39,18 @@ struct linespec_result;
 struct linespec_sals;
 struct event_location;
 
+/* Why are we removing the breakpoint from the target?  */
+
+enum remove_bp_reason
+{
+  /* A regular remove.  Remove the breakpoint and forget everything
+     about it.  */
+  REMOVE_BREAKPOINT,
+
+  /* Detach the breakpoints from a fork child.  */
+  DETACH_BREAKPOINT,
+};
+
 /* This is the maximum number of bytes a breakpoint instruction can
    take.  Feel free to increase it.  It's just used in a few places to
    size arrays that should be independent of the target
@@ -519,7 +531,7 @@ struct breakpoint_ops
      with the "insert" method above.  Return 0 for success, 1 if the
      breakpoint, watchpoint or catchpoint type is not supported,
      -1 for failure.  */
-  int (*remove_location) (struct bp_location *);
+  int (*remove_location) (struct bp_location *, enum remove_bp_reason reason);
 
   /* Return true if it the target has stopped due to hitting
      breakpoint location BL.  This function does not check if we
diff --git a/gdb/corelow.c b/gdb/corelow.c
index 224719e..376b7c9 100644
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -920,6 +920,16 @@ ignore (struct target_ops *ops, struct gdbarch *gdbarch,
   return 0;
 }
 
+/* Implement the to_remove_breakpoint method.  */
+
+static int
+core_remove_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
+			struct bp_target_info *bp_tgt,
+			enum remove_bp_reason reason)
+{
+  return 0;
+}
+
 
 /* Okay, let's be honest: threads gleaned from a core file aren't
    exactly lively, are they?  On the other hand, if we don't claim
@@ -1043,7 +1053,7 @@ init_core_ops (void)
   core_ops.to_xfer_partial = core_xfer_partial;
   core_ops.to_files_info = core_files_info;
   core_ops.to_insert_breakpoint = ignore;
-  core_ops.to_remove_breakpoint = ignore;
+  core_ops.to_remove_breakpoint = core_remove_breakpoint;
   core_ops.to_thread_alive = core_thread_alive;
   core_ops.to_read_description = core_read_description;
   core_ops.to_pid_to_str = core_pid_to_str;
diff --git a/gdb/exec.c b/gdb/exec.c
index 23c89c2..d7f42a2 100644
--- a/gdb/exec.c
+++ b/gdb/exec.c
@@ -1005,6 +1005,16 @@ ignore (struct target_ops *ops, struct gdbarch *gdbarch,
   return 0;
 }
 
+/* Implement the to_remove_breakpoint method.  */
+
+static int
+exec_remove_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
+			struct bp_target_info *bp_tgt,
+			enum remove_bp_reason reason)
+{
+  return 0;
+}
+
 static int
 exec_has_memory (struct target_ops *ops)
 {
@@ -1036,7 +1046,7 @@ Specify the filename of the executable file.";
   exec_ops.to_get_section_table = exec_get_section_table;
   exec_ops.to_files_info = exec_files_info;
   exec_ops.to_insert_breakpoint = ignore;
-  exec_ops.to_remove_breakpoint = ignore;
+  exec_ops.to_remove_breakpoint = exec_remove_breakpoint;
   exec_ops.to_stratum = file_stratum;
   exec_ops.to_has_memory = exec_has_memory;
   exec_ops.to_make_corefile_notes = exec_make_note_section;
diff --git a/gdb/mem-break.c b/gdb/mem-break.c
index 9bb4c45..803f62b 100644
--- a/gdb/mem-break.c
+++ b/gdb/mem-break.c
@@ -93,7 +93,8 @@ memory_insert_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
 
 int
 memory_remove_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
-			  struct bp_target_info *bp_tgt)
+			  struct bp_target_info *bp_tgt,
+			  enum remove_bp_reason reason)
 {
   return gdbarch_memory_remove_breakpoint (gdbarch, bp_tgt);
 }
diff --git a/gdb/nto-procfs.c b/gdb/nto-procfs.c
index 992de29..cd715d2 100644
--- a/gdb/nto-procfs.c
+++ b/gdb/nto-procfs.c
@@ -1015,7 +1015,8 @@ procfs_insert_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
 
 static int
 procfs_remove_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
-			  struct bp_target_info *bp_tgt)
+			  struct bp_target_info *bp_tgt,
+			  enum remove_bp_reason reason)
 {
   return procfs_breakpoint (bp_tgt->placed_address, _DEBUG_BREAK_EXEC, -1);
 }
diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index 77b5180..6a5ffa4 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -1406,7 +1406,8 @@ record_btrace_insert_breakpoint (struct target_ops *ops,
 static int
 record_btrace_remove_breakpoint (struct target_ops *ops,
 				 struct gdbarch *gdbarch,
-				 struct bp_target_info *bp_tgt)
+				 struct bp_target_info *bp_tgt,
+				 enum remove_bp_reason reason)
 {
   const char *old;
   int ret;
@@ -1419,7 +1420,8 @@ record_btrace_remove_breakpoint (struct target_ops *ops,
   ret = 0;
   TRY
     {
-      ret = ops->beneath->to_remove_breakpoint (ops->beneath, gdbarch, bp_tgt);
+      ret = ops->beneath->to_remove_breakpoint (ops->beneath, gdbarch, bp_tgt,
+						reason);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
diff --git a/gdb/record-full.c b/gdb/record-full.c
index f6023bf..418a346 100644
--- a/gdb/record-full.c
+++ b/gdb/record-full.c
@@ -1684,7 +1684,8 @@ record_full_insert_breakpoint (struct target_ops *ops,
 static int
 record_full_remove_breakpoint (struct target_ops *ops,
 			       struct gdbarch *gdbarch,
-			       struct bp_target_info *bp_tgt)
+			       struct bp_target_info *bp_tgt,
+			       enum remove_bp_reason reason)
 {
   struct record_full_breakpoint *bp;
   int ix;
@@ -1704,7 +1705,7 @@ record_full_remove_breakpoint (struct target_ops *ops,
 
 	      old_cleanups = record_full_gdb_operation_disable_set ();
 	      ret = ops->beneath->to_remove_breakpoint (ops->beneath, gdbarch,
-							bp_tgt);
+							bp_tgt, reason);
 	      do_cleanups (old_cleanups);
 
 	      if (ret != 0)
@@ -2171,7 +2172,8 @@ record_full_core_insert_breakpoint (struct target_ops *ops,
 static int
 record_full_core_remove_breakpoint (struct target_ops *ops,
 				    struct gdbarch *gdbarch,
-				    struct bp_target_info *bp_tgt)
+				    struct bp_target_info *bp_tgt,
+				    enum remove_bp_reason reason)
 {
   return 0;
 }
diff --git a/gdb/remote-m32r-sdi.c b/gdb/remote-m32r-sdi.c
index c1bd858..25e51f0 100644
--- a/gdb/remote-m32r-sdi.c
+++ b/gdb/remote-m32r-sdi.c
@@ -1216,7 +1216,8 @@ m32r_insert_breakpoint (struct target_ops *ops,
 static int
 m32r_remove_breakpoint (struct target_ops *ops,
 			struct gdbarch *gdbarch,
-			struct bp_target_info *bp_tgt)
+			struct bp_target_info *bp_tgt,
+			enum remove_bp_reason reason)
 {
   CORE_ADDR addr = bp_tgt->placed_address;
   int i;
diff --git a/gdb/remote-mips.c b/gdb/remote-mips.c
index 2f6663b..31aae9b 100644
--- a/gdb/remote-mips.c
+++ b/gdb/remote-mips.c
@@ -2387,13 +2387,14 @@ mips_insert_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
 
 static int
 mips_remove_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
-			struct bp_target_info *bp_tgt)
+			struct bp_target_info *bp_tgt,
+			enum remove_bp_reason reason)
 {
   if (monitor_supports_breakpoints)
     return mips_clear_breakpoint (bp_tgt->placed_address, MIPS_INSN32_SIZE,
 				  BREAK_FETCH);
   else
-    return memory_remove_breakpoint (ops, gdbarch, bp_tgt);
+    return memory_remove_breakpoint (ops, gdbarch, bp_tgt, reason);
 }
 
 /* Tell whether this target can support a hardware breakpoint.  CNT
diff --git a/gdb/remote.c b/gdb/remote.c
index 6d56f19..404a5c6 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -9339,7 +9339,8 @@ Target doesn't support breakpoints that have target side commands."));
 static int
 remote_remove_breakpoint (struct target_ops *ops,
 			  struct gdbarch *gdbarch,
-			  struct bp_target_info *bp_tgt)
+			  struct bp_target_info *bp_tgt,
+			  enum remove_bp_reason reason)
 {
   CORE_ADDR addr = bp_tgt->placed_address;
   struct remote_state *rs = get_remote_state ();
@@ -9368,7 +9369,7 @@ remote_remove_breakpoint (struct target_ops *ops,
       return (rs->buf[0] == 'E');
     }
 
-  return memory_remove_breakpoint (ops, gdbarch, bp_tgt);
+  return memory_remove_breakpoint (ops, gdbarch, bp_tgt, reason);
 }
 
 static enum Z_packet_type
diff --git a/gdb/target-debug.h b/gdb/target-debug.h
index 5f44d11..ef7e14d 100644
--- a/gdb/target-debug.h
+++ b/gdb/target-debug.h
@@ -158,6 +158,8 @@
   target_debug_do_print (plongest (X))
 #define target_debug_print_struct_inferior_p(X)	\
   target_debug_do_print (host_address_to_string (X))
+#define target_debug_print_enum_remove_bp_reason(X) \
+  target_debug_do_print (plongest (X))
 
 static void
 target_debug_print_struct_target_waitstatus_p (struct target_waitstatus *status)
diff --git a/gdb/target-delegates.c b/gdb/target-delegates.c
index d23bc75..e21746f 100644
--- a/gdb/target-delegates.c
+++ b/gdb/target-delegates.c
@@ -262,24 +262,26 @@ debug_insert_breakpoint (struct target_ops *self, struct gdbarch *arg1, struct b
 }
 
 static int
-delegate_remove_breakpoint (struct target_ops *self, struct gdbarch *arg1, struct bp_target_info *arg2)
+delegate_remove_breakpoint (struct target_ops *self, struct gdbarch *arg1, struct bp_target_info *arg2, enum remove_bp_reason arg3)
 {
   self = self->beneath;
-  return self->to_remove_breakpoint (self, arg1, arg2);
+  return self->to_remove_breakpoint (self, arg1, arg2, arg3);
 }
 
 static int
-debug_remove_breakpoint (struct target_ops *self, struct gdbarch *arg1, struct bp_target_info *arg2)
+debug_remove_breakpoint (struct target_ops *self, struct gdbarch *arg1, struct bp_target_info *arg2, enum remove_bp_reason arg3)
 {
   int result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->to_remove_breakpoint (...)\n", debug_target.to_shortname);
-  result = debug_target.to_remove_breakpoint (&debug_target, arg1, arg2);
+  result = debug_target.to_remove_breakpoint (&debug_target, arg1, arg2, arg3);
   fprintf_unfiltered (gdb_stdlog, "<- %s->to_remove_breakpoint (", debug_target.to_shortname);
   target_debug_print_struct_target_ops_p (&debug_target);
   fputs_unfiltered (", ", gdb_stdlog);
   target_debug_print_struct_gdbarch_p (arg1);
   fputs_unfiltered (", ", gdb_stdlog);
   target_debug_print_struct_bp_target_info_p (arg2);
+  fputs_unfiltered (", ", gdb_stdlog);
+  target_debug_print_enum_remove_bp_reason (arg3);
   fputs_unfiltered (") = ", gdb_stdlog);
   target_debug_print_int (result);
   fputs_unfiltered ("\n", gdb_stdlog);
diff --git a/gdb/target.c b/gdb/target.c
index ac66a3a..a0d5937 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -2081,7 +2081,8 @@ target_insert_breakpoint (struct gdbarch *gdbarch,
 
 int
 target_remove_breakpoint (struct gdbarch *gdbarch,
-			  struct bp_target_info *bp_tgt)
+			  struct bp_target_info *bp_tgt,
+			  enum remove_bp_reason reason)
 {
   /* This is kind of a weird case to handle, but the permission might
      have been changed after breakpoints were inserted - in which case
@@ -2094,7 +2095,7 @@ target_remove_breakpoint (struct gdbarch *gdbarch,
     }
 
   return current_target.to_remove_breakpoint (&current_target,
-					      gdbarch, bp_tgt);
+					      gdbarch, bp_tgt, reason);
 }
 
 static void
diff --git a/gdb/target.h b/gdb/target.h
index e1419a9..7c8513a 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -478,7 +478,8 @@ struct target_ops
 				 struct bp_target_info *)
       TARGET_DEFAULT_FUNC (memory_insert_breakpoint);
     int (*to_remove_breakpoint) (struct target_ops *, struct gdbarch *,
-				 struct bp_target_info *)
+				 struct bp_target_info *,
+				 enum remove_bp_reason)
       TARGET_DEFAULT_FUNC (memory_remove_breakpoint);
 
     /* Returns true if the target stopped because it executed a
@@ -1496,7 +1497,8 @@ extern int target_insert_breakpoint (struct gdbarch *gdbarch,
    machine.  Result is 0 for success, non-zero for error.  */
 
 extern int target_remove_breakpoint (struct gdbarch *gdbarch,
-				     struct bp_target_info *bp_tgt);
+				     struct bp_target_info *bp_tgt,
+				     enum remove_bp_reason reason);
 
 /* Returns true if the terminal settings of the inferior are in
    effect.  */
@@ -2356,7 +2358,8 @@ extern struct target_section_table *target_get_section_table
 /* From mem-break.c */
 
 extern int memory_remove_breakpoint (struct target_ops *, struct gdbarch *,
-				     struct bp_target_info *);
+				     struct bp_target_info *,
+				     enum remove_bp_reason);
 
 extern int memory_insert_breakpoint (struct target_ops *, struct gdbarch *,
 				     struct bp_target_info *);
-- 
1.9.3


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/4] Fix PR gdb/19187 (process record over a fork causes internal error)
  2016-02-14 18:37 [PATCH 0/4] Fix PR gdb/19187 (process record over a fork causes internal error) Pedro Alves
                   ` (3 preceding siblings ...)
  2016-02-14 18:44 ` [PATCH 4/4] Fix PR gdb/19187 (process record over a fork causes internal error) Pedro Alves
@ 2016-08-10 22:11 ` Pedro Alves
  4 siblings, 0 replies; 8+ messages in thread
From: Pedro Alves @ 2016-08-10 22:11 UTC (permalink / raw)
  To: gdb-patches

Yao reminded me about this series, and asked about putting it in 7.12.

I've done so now: pushed to master and 7.12 branch.

Thanks,
Pedro Alves

On 02/14/2016 06:37 PM, Pedro Alves wrote:
> This series fixes:
> 
>  (gdb) record
>  break marker2
>  Breakpoint 2 at 0x40067a: file /home/pedro/gdb/mygit/src/gdb/testsuite/gdb.reverse/waitpid-reverse.c, line 30.
>  (gdb) PASS: gdb.reverse/waitpid-reverse.exp: set breakpoint at marker2
>  continue
>  Continuing.
>  /home/pedro/gdb/mygit/src/gdb/record-full.c:1720: internal-error: record_full_remove_breakpoint: removing unknown breakpoint
>  A problem internal to GDB has been detected,
>  further debugging may prove unreliable.
>  Quit this debugging session? (y or n)
>  KFAIL: gdb.reverse/waitpid-reverse.exp: continue to breakpoint: marker2 (GDB internal error) (PRMS: gdb/19187)
> 
> The problem is that the target side can't distinguish between deleting
> a breakpoint and detaching a breakpoint.
> 
> Right after a fork is detected, we detach breakpoints from the child
> (detach_breakpoints), which calls into target_remove_breakpoint with
> inferior_ptid pointing at the child process, but leaves the breakpoint
> marked inserted (in the parent).
> 
> Since record-full.c's target_remove_breakpoint implementation doesn't
> know we're detaching a breakpoint, it removes the breakpoint from its
> own breakpoint table.
> 
> Then when we later remove the breakpoint from the parent, we fail that
> assertion, since the breakpoint is unexpectedly not found in the
> record-full.c breakpoint table.
> 
> The first three patches pass down the reason for removing the
> breakpoint all the way to the target.
> 
> Patch 4 then simply makes record-full.c not delete the breakpoint from
> its breakpoint table when we're detaching the breakpoint from a fork
> child.
> 
> Pedro Alves (4):
>   Simplify remove_breakpoint interface
>   Introduce 'enum remove_bp_reason'
>   Plumb enum remove_bp_reason all the way to target_remove_breakpoint
>   Fix PR gdb/19187 (process record over a fork causes internal error)
> 
>  gdb/break-catch-sig.c                         |  3 +-
>  gdb/break-catch-syscall.c                     |  2 +-
>  gdb/breakpoint.c                              | 70 +++++++++++++--------------
>  gdb/breakpoint.h                              | 14 +++++-
>  gdb/corelow.c                                 | 10 +++-
>  gdb/exec.c                                    | 10 +++-
>  gdb/mem-break.c                               |  3 +-
>  gdb/record-btrace.c                           |  6 ++-
>  gdb/record-full.c                             | 15 ++++--
>  gdb/remote.c                                  |  5 +-
>  gdb/target-debug.h                            |  2 +
>  gdb/target-delegates.c                        | 10 ++--
>  gdb/target.c                                  |  5 +-
>  gdb/target.h                                  |  9 ++--
>  gdb/testsuite/gdb.reverse/waitpid-reverse.exp |  4 +-
>  15 files changed, 105 insertions(+), 63 deletions(-)
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2016-08-10 22:11 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-14 18:37 [PATCH 0/4] Fix PR gdb/19187 (process record over a fork causes internal error) Pedro Alves
2016-02-14 18:37 ` [PATCH 3/4] Plumb enum remove_bp_reason all the way to target_remove_breakpoint Pedro Alves
2016-02-15  9:12   ` Yao Qi
2016-02-15 14:41     ` Pedro Alves
2016-02-14 18:37 ` [PATCH 1/4] Simplify remove_breakpoint interface Pedro Alves
2016-02-14 18:37 ` [PATCH 2/4] Introduce 'enum remove_bp_reason' Pedro Alves
2016-02-14 18:44 ` [PATCH 4/4] Fix PR gdb/19187 (process record over a fork causes internal error) Pedro Alves
2016-08-10 22:11 ` [PATCH 0/4] " Pedro Alves

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).