public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Don Breazeal <donb@codesourcery.com>
To: <gdb-patches@sourceware.org>, <palves@redhat.com>
Subject: [PATCH v6 2/6] Clone remote breakpoints
Date: Tue, 17 Mar 2015 20:57:00 -0000	[thread overview]
Message-ID: <1426625788-4469-3-git-send-email-donb@codesourcery.com> (raw)
In-Reply-To: <1426625788-4469-1-git-send-email-donb@codesourcery.com>

This version of this patch is unchanged except possibly for merges from
the mainline.  The last review+response was here:
https://sourceware.org/ml/gdb-patches/2014-10/msg00883.html.

Thanks!
--Don

This patch implements gdbserver routines to clone the breakpoint lists of a
process, duplicating them for another process.  In gdbserver, each process
maintains its own independent breakpoint list.  When a fork call creates a
child, all of the breakpoints currently inserted in the parent process are
also inserted in the child process, but there is nothing to describe them
in the data structures related to the child.  The child must have a
breakpoint list describing them so that they can be removed (if detaching)
or recognized (if following).  Implementation is a mechanical process of
just cloning the lists in several new functions in gdbserver/mem-break.c.

Tested by building, since none of the new functions are called yet.  This
was tested with another patch in the series that implements follow-fork.

gdb/gdbserver/
2015-03-17  Don Breazeal  <donb@codesourcery.com>

        * mem-break.c (APPEND_TO_LIST): Define macro.
        (clone_agent_expr): New function.
        (clone_one_breakpoint): New function.
        (clone_all_breakpoints): New function.
        * mem-break.h: Declare new functions.

---
 gdb/gdbserver/mem-break.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++
 gdb/gdbserver/mem-break.h |   6 +++
 2 files changed, 111 insertions(+)

diff --git a/gdb/gdbserver/mem-break.c b/gdb/gdbserver/mem-break.c
index 70fab2e..d1b66bf 100644
--- a/gdb/gdbserver/mem-break.c
+++ b/gdb/gdbserver/mem-break.c
@@ -28,6 +28,24 @@ int breakpoint_len;
 
 #define MAX_BREAKPOINT_LEN 8
 
+/* Helper macro used in loops that append multiple items to a singly-linked
+   list instead of inserting items at the head of the list, as, say, in the
+   breakpoint lists.  LISTPP is a pointer to the pointer that is the head of
+   the new list.  ITEMP is a pointer to the item to be added to the list.
+   TAILP must be defined to be the same type as ITEMP, and initialized to
+   NULL.  */
+
+#define APPEND_TO_LIST(listpp, itemp, tailp) \
+	  do \
+	    { \
+	      if ((tailp) == NULL) \
+		*(listpp) = (itemp); \
+	      else \
+		(tailp)->next = (itemp); \
+	      (tailp) = (itemp); \
+	    } \
+	  while (0)
+
 /* GDB will never try to install multiple breakpoints at the same
    address.  However, we can see GDB requesting to insert a breakpoint
    at an address is had already inserted one previously in a few
@@ -1913,3 +1931,90 @@ free_all_breakpoints (struct process_info *proc)
   while (proc->breakpoints)
     delete_breakpoint_1 (proc, proc->breakpoints);
 }
+
+/* Clone an agent expression.  */
+
+static struct agent_expr *
+clone_agent_expr (const struct agent_expr *src_ax)
+{
+  struct agent_expr *ax;
+
+  ax = xcalloc (1, sizeof (*ax));
+  ax->length = src_ax->length;
+  ax->bytes = xcalloc (ax->length, 1);
+  memcpy (ax->bytes, src_ax->bytes, ax->length);
+  return ax;
+}
+
+/* Deep-copy the contents of one breakpoint to another.  */
+
+static struct breakpoint *
+clone_one_breakpoint (const struct breakpoint *src)
+{
+  struct breakpoint *dest;
+  struct raw_breakpoint *dest_raw;
+  struct point_cond_list *current_cond;
+  struct point_cond_list *new_cond;
+  struct point_cond_list *cond_tail = NULL;
+  struct point_command_list *current_cmd;
+  struct point_command_list *new_cmd;
+  struct point_command_list *cmd_tail = NULL;
+
+  /* Clone the raw breakpoint.  */
+  dest_raw = xcalloc (1, sizeof (*dest_raw));
+  dest_raw->raw_type = src->raw->raw_type;
+  dest_raw->refcount = src->raw->refcount;
+  dest_raw->pc = src->raw->pc;
+  dest_raw->size = src->raw->size;
+  memcpy (dest_raw->old_data, src->raw->old_data, MAX_BREAKPOINT_LEN);
+  dest_raw->inserted = src->raw->inserted;
+
+  /* Clone the high-level breakpoint.  */
+  dest = xcalloc (1, sizeof (*dest));
+  dest->type = src->type;
+  dest->raw = dest_raw;
+  dest->handler = src->handler;
+
+  /* Clone the condition list.  */
+  for (current_cond = src->cond_list; current_cond != NULL;
+       current_cond = current_cond->next)
+    {
+      new_cond = xcalloc (1, sizeof (*new_cond));
+      new_cond->cond = clone_agent_expr (current_cond->cond);
+      APPEND_TO_LIST (&dest->cond_list, new_cond, cond_tail);
+    }
+
+  /* Clone the command list.  */
+  for (current_cmd = src->command_list; current_cmd != NULL;
+       current_cmd = current_cmd->next)
+    {
+      new_cmd = xcalloc (1, sizeof (*new_cmd));
+      new_cmd->cmd = clone_agent_expr (current_cmd->cmd);
+      new_cmd->persistence = current_cmd->persistence;
+      APPEND_TO_LIST (&dest->command_list, new_cmd, cmd_tail);
+    }
+
+  return dest;
+}
+
+/* Create a new breakpoint list NEW_LIST that is a copy of the
+   list starting at SRC_LIST.  Create the corresponding new
+   raw_breakpoint list NEW_RAW_LIST as well.  */
+
+void
+clone_all_breakpoints (struct breakpoint **new_list,
+		       struct raw_breakpoint **new_raw_list,
+		       const struct breakpoint *src_list)
+{
+  const struct breakpoint *bp;
+  struct breakpoint *new_bkpt;
+  struct breakpoint *bkpt_tail = NULL;
+  struct raw_breakpoint *raw_bkpt_tail = NULL;
+
+  for (bp = src_list; bp != NULL; bp = bp->next)
+    {
+      new_bkpt = clone_one_breakpoint (bp);
+      APPEND_TO_LIST (new_list, new_bkpt, bkpt_tail);
+      APPEND_TO_LIST (new_raw_list, new_bkpt->raw, raw_bkpt_tail);
+    }
+}
diff --git a/gdb/gdbserver/mem-break.h b/gdb/gdbserver/mem-break.h
index 8b010c1..b5a3208 100644
--- a/gdb/gdbserver/mem-break.h
+++ b/gdb/gdbserver/mem-break.h
@@ -253,4 +253,10 @@ int insert_memory_breakpoint (struct raw_breakpoint *bp);
 
 int remove_memory_breakpoint (struct raw_breakpoint *bp);
 
+/* Create a new breakpoint list NEW_BKPT_LIST that is a copy of SRC.  */
+
+void clone_all_breakpoints (struct breakpoint **new_bkpt_list,
+			    struct raw_breakpoint **new_raw_bkpt_list,
+			    const struct breakpoint *src);
+
 #endif /* MEM_BREAK_H */
-- 
1.8.1.1

  parent reply	other threads:[~2015-03-17 20:57 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <201501252151.t0PLo3jE018308@mx0b-0013c101.pphosted.com>
2015-01-26  4:43 ` [PATCH v4 0/7] Remote fork events Breazeal, Don
2015-02-06 20:02   ` Breazeal, Don
2015-02-27  0:46   ` [PATCH v5 0/6] " Don Breazeal
2015-02-27  0:46     ` [PATCH v5 01/06] Identify remote fork event support Don Breazeal
2015-02-27  0:47     ` [PATCH v5 04/06] Arch-specific remote follow fork Don Breazeal
2015-02-27  7:37       ` Eli Zaretskii
2015-02-27  0:47     ` [PATCH v5 05/06] Remote follow vfork Don Breazeal
2015-02-27  0:47     ` [PATCH v5 03/06] Extended-remote Linux follow fork Don Breazeal
2015-02-27  0:47     ` [PATCH v5 02/06] Clone remote breakpoints Don Breazeal
2015-02-27  0:48     ` [PATCH v5 06/06] Remote fork catch Don Breazeal
2015-03-02 18:29     ` [PATCH v5 0/6] Remote fork events Pedro Alves
2015-03-02 20:18     ` [PATCH] Tighten gdb.base/disp-step-syscall.exp (was: Re: [PATCH v5 0/6] Remote fork events) Pedro Alves
2015-03-03  6:20       ` [PATCH] Tighten gdb.base/disp-step-syscall.exp Breazeal, Don
2015-03-03 15:01         ` Pedro Alves
2015-03-17 21:18       ` Breazeal, Don
2015-03-18 19:37         ` Pedro Alves
2015-03-17 20:56     ` [PATCH v6 0/6] Remote fork events Don Breazeal
2015-03-17 20:56       ` [PATCH v6 1/6] Identify remote fork event support Don Breazeal
2015-03-24 10:57         ` Pedro Alves
2015-03-26 19:00           ` [PATCH v5 01/06] " Don Breazeal
2015-03-27 11:14             ` Pedro Alves
2015-03-17 20:57       ` [PATCH v6 4/6] Arch-specific remote follow fork Don Breazeal
2015-03-17 20:57       ` Don Breazeal [this message]
2015-03-17 20:57       ` [PATCH v6 3/6] Extended-remote Linux " Don Breazeal
2015-03-24 12:17         ` Pedro Alves
2015-04-07 17:35           ` Pedro Alves
2015-03-17 20:58       ` [PATCH v6 5/6] Remote follow vfork Don Breazeal
2015-03-24 12:28         ` Pedro Alves
2015-03-17 20:58       ` [PATCH v6 6/6] Remote fork catch Don Breazeal
2015-03-24 12:47         ` Pedro Alves

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1426625788-4469-3-git-send-email-donb@codesourcery.com \
    --to=donb@codesourcery.com \
    --cc=gdb-patches@sourceware.org \
    --cc=palves@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).