Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Vladimir Prus <vladimir@codesourcery.com>
To: gdb-patches@sources.redhat.com
Subject: [RFA] Try2: Ignore breakpoints when reading memory.
Date: Sun, 24 Feb 2008 14:58:00 -0000	[thread overview]
Message-ID: <200802241750.41264.vladimir@codesourcery.com> (raw)


This a second attempt at making gdb always ignore
any memory breakpoints that are inserted and show the original
memory content. This patch is the immediate prerequisite for the
patch that makes breakpoints always inserted.

Unlike the previous patch, there's a mechanism to:
1. Control the new behaviour from command line.
2. Temporary force specific behavior, if some code
needs it.

OK?

- Volodya

	* breakpoint.h (breakpoint_restore_shadows): New
	declaration.
	* breakpoint.c (breakpoint_restore_shadows): New.
	(read_memory_nobpt): Use breakpoint_restore_shadows.
	* target.c (memory_xfer_partial): Call
	breakpoint_restore_shadows.
	(restore_show_memory_breakpoints)
	(make_show_memory_beakpoints_cleanup): New.
	(show_memory_breakpoints, show_show_memory_breakpoints): New.
	(initialize_targets): Register set/show 'show-memory-breakpoints'.
	* target.h (make_show_memory_beakpoints_cleanup): Declare.
	* ppc-linux-tdep.c (ppc_linux_memory_remove_breakpoint):
	Make sure we see memory breakpoints when checking if
	breakpoint is still there.
---
 gdb/breakpoint.c     |   83 +++++++++++++++++++++----------------------------
 gdb/breakpoint.h     |    4 ++
 gdb/ppc-linux-tdep.c |    4 ++
 gdb/target.c         |   52 +++++++++++++++++++++++++++++--
 gdb/target.h         |    5 +++
 5 files changed, 98 insertions(+), 50 deletions(-)

diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index dca4ca1..9a7800c 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -712,14 +712,26 @@ commands_from_control_command (char *arg, struct command_line *cmd)
 int
 read_memory_nobpt (CORE_ADDR memaddr, gdb_byte *myaddr, unsigned len)
 {
-  int status;
-  const struct bp_location *b;
+  int status = 0;
+  /* Make sure the following read will ignore memory breakpoints.  */
+  struct cleanup *cleanup = make_show_memory_breakpoints_cleanup (0);
+
+  status = target_read_memory (memaddr, myaddr, len);
+
+  do_cleanups (cleanup);
+
+  return status;
+}
+
+void
+breakpoint_restore_shadows (gdb_byte *buf,
+			    ULONGEST memaddr, 
+			    LONGEST len)
+{
+  struct bp_location *b;
   CORE_ADDR bp_addr = 0;
   int bp_size = 0;
-
-  if (gdbarch_breakpoint_from_pc (current_gdbarch, &bp_addr, &bp_size) == NULL)
-    /* No breakpoints on this machine. */
-    return target_read_memory (memaddr, myaddr, len);
+  int bptoffset = 0;
 
   ALL_BP_LOCATIONS (b)
   {
@@ -738,60 +750,37 @@ read_memory_nobpt (CORE_ADDR memaddr, gdb_byte *myaddr, unsigned len)
     if (bp_size == 0)
       /* bp isn't valid, or doesn't shadow memory.  */
       continue;
+
     if (bp_addr + bp_size <= memaddr)
       /* The breakpoint is entirely before the chunk of memory we
          are reading.  */
       continue;
+
     if (bp_addr >= memaddr + len)
       /* The breakpoint is entirely after the chunk of memory we are
          reading. */
       continue;
-    /* Copy the breakpoint from the shadow contents, and recurse for
-       the things before and after.  */
-    {
-      /* Offset within shadow_contents.  */
-      int bptoffset = 0;
-
-      if (bp_addr < memaddr)
-	{
-	  /* Only copy the second part of the breakpoint.  */
-	  bp_size -= memaddr - bp_addr;
-	  bptoffset = memaddr - bp_addr;
-	  bp_addr = memaddr;
-	}
 
-      if (bp_addr + bp_size > memaddr + len)
-	{
-	  /* Only copy the first part of the breakpoint.  */
-	  bp_size -= (bp_addr + bp_size) - (memaddr + len);
-	}
-
-      memcpy (myaddr + bp_addr - memaddr,
-	      b->target_info.shadow_contents + bptoffset, bp_size);
+    /* Offset within shadow_contents.  */
+    if (bp_addr < memaddr)
+      {
+	/* Only copy the second part of the breakpoint.  */
+	bp_size -= memaddr - bp_addr;
+	bptoffset = memaddr - bp_addr;
+	bp_addr = memaddr;
+      }
 
-      if (bp_addr > memaddr)
-	{
-	  /* Copy the section of memory before the breakpoint.  */
-	  status = read_memory_nobpt (memaddr, myaddr, bp_addr - memaddr);
-	  if (status != 0)
-	    return status;
-	}
+    if (bp_addr + bp_size > memaddr + len)
+      {
+	/* Only copy the first part of the breakpoint.  */
+	bp_size -= (bp_addr + bp_size) - (memaddr + len);
+      }
 
-      if (bp_addr + bp_size < memaddr + len)
-	{
-	  /* Copy the section of memory after the breakpoint.  */
-	  status = read_memory_nobpt (bp_addr + bp_size,
-				      myaddr + bp_addr + bp_size - memaddr,
-				      memaddr + len - (bp_addr + bp_size));
-	  if (status != 0)
-	    return status;
-	}
-      return 0;
-    }
+    memcpy (buf + bp_addr - memaddr,
+	    b->target_info.shadow_contents + bptoffset, bp_size);
   }
-  /* Nothing overlaps.  Just call read_memory_noerr.  */
-  return target_read_memory (memaddr, myaddr, len);
 }
+
 \f
 
 /* A wrapper function for inserting catchpoints.  */
diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
index 41730c0..159c406 100644
--- a/gdb/breakpoint.h
+++ b/gdb/breakpoint.h
@@ -854,4 +854,8 @@ extern int deprecated_remove_raw_breakpoint (void *);
    target.  */
 int watchpoints_triggered (struct target_waitstatus *);
 
+extern void breakpoint_restore_shadows (gdb_byte *buf,
+					ULONGEST memaddr, 
+					LONGEST len);
+
 #endif /* !defined (BREAKPOINT_H) */
diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c
index 4b35f7f..bf084f5 100644
--- a/gdb/ppc-linux-tdep.c
+++ b/gdb/ppc-linux-tdep.c
@@ -280,12 +280,15 @@ ppc_linux_memory_remove_breakpoint (struct bp_target_info *bp_tgt)
   int val;
   int bplen;
   gdb_byte old_contents[BREAKPOINT_MAX];
+  struct cleanup *cleanup;
 
   /* Determine appropriate breakpoint contents and size for this address.  */
   bp = gdbarch_breakpoint_from_pc (current_gdbarch, &addr, &bplen);
   if (bp == NULL)
     error (_("Software breakpoints not implemented for this target."));
 
+  /* Make sure we see the memory breakpoints.  */
+  cleanup = make_show_memory_breakpoints_cleanup (1);
   val = target_read_memory (addr, old_contents, bplen);
 
   /* If our breakpoint is no longer at the address, this means that the
@@ -294,6 +297,7 @@ ppc_linux_memory_remove_breakpoint (struct bp_target_info *bp_tgt)
   if (val == 0 && memcmp (bp, old_contents, bplen) == 0)
     val = target_write_memory (addr, bp_tgt->shadow_contents, bplen);
 
+  do_cleanups (cleanup);
   return val;
 }
 
diff --git a/gdb/target.c b/gdb/target.c
index 87ddf24..32271eb 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -203,6 +203,18 @@ int attach_flag;
 
 static int trust_readonly = 0;
 
+/* Nonzero if we should show true memory content including
+   memory breakpoint inserted by gdb.  */
+
+static int show_memory_breakpoints = 0;
+
+static void 
+show_show_memory_breakpoints (struct ui_file *file, int from_tty,
+			      struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (file, _("Memory breakpoints show mode is %s.\n"), value);
+}
+
 /* Non-zero if we want to see trace of target level stuff.  */
 
 static int targetdebug = 0;
@@ -1064,7 +1076,11 @@ memory_xfer_partial (struct target_ops *ops, void *readbuf, const void *writebuf
       if (res <= 0)
 	return -1;
       else
-	return res;
+	{
+	  if (readbuf && !show_memory_breakpoints)
+	    breakpoint_restore_shadows (readbuf, memaddr, reg_len);
+	  return res;
+	}
     }
 
   /* If none of those methods found the memory we wanted, fall back
@@ -1082,22 +1098,40 @@ memory_xfer_partial (struct target_ops *ops, void *readbuf, const void *writebuf
       res = ops->to_xfer_partial (ops, TARGET_OBJECT_MEMORY, NULL,
 				  readbuf, writebuf, memaddr, reg_len);
       if (res > 0)
-	return res;
+	break;
 
       /* We want to continue past core files to executables, but not
 	 past a running target's memory.  */
       if (ops->to_has_all_memory)
-	return res;
+	break;
 
       ops = ops->beneath;
     }
   while (ops != NULL);
 
+  if (readbuf && !show_memory_breakpoints)
+    breakpoint_restore_shadows (readbuf, memaddr, reg_len);
+
   /* If we still haven't got anything, return the last error.  We
      give up.  */
   return res;
 }
 
+static void
+restore_show_memory_breakpoints (void *arg)
+{
+  show_memory_breakpoints = (int)arg;
+}
+
+struct cleanup *
+make_show_memory_breakpoints_cleanup (int show)
+{
+  int current = show_memory_breakpoints;
+  show_memory_breakpoints = show;
+
+  return make_cleanup (restore_show_memory_breakpoints, (void *)current);
+}
+
 static LONGEST
 target_xfer_partial (struct target_ops *ops,
 		     enum target_object object, const char *annex,
@@ -2798,6 +2832,18 @@ result in significant performance improvement for remote targets."),
 			   show_trust_readonly,
 			   &setlist, &showlist);
 
+  add_setshow_boolean_cmd ("show-memory-breakpoints", class_support,
+			   &show_memory_breakpoints, _("\
+Set mode for showing memory breakpoints."), _("\
+Show mode for showing memory breakpoints."), _("\
+When this mode is off (which is default), all memory reads will return\n\
+memory content as if no memory breakpoint were inserted.  When this mode\n\
+if on, memory reads will see inserted memory breakpoints.  In particular,\n\
+the disassemble command will show the breakpoint instructions."),
+			   NULL,
+			   show_show_memory_breakpoints,
+			   &setlist, &showlist);
+
   add_com ("monitor", class_obscure, do_monitor_command,
 	   _("Send a command to the remote monitor (remote targets only)."));
 
diff --git a/gdb/target.h b/gdb/target.h
index 3f332fd..dcc5cee 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -1248,6 +1248,11 @@ extern enum target_signal target_signal_from_command (int);
 
 /* Any target can call this to switch to remote protocol (in remote.c). */
 extern void push_remote_target (char *name, int from_tty);
+
+/* Set the show memory breakpoints mode to show, and installs a cleanup
+   to restore it back to the current value.  */
+extern struct cleanup * make_show_memory_breakpoints_cleanup (int show);
+
 \f
 /* Imported from machine dependent code */
 
-- 
1.5.3.5


             reply	other threads:[~2008-02-24 14:51 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-02-24 14:58 Vladimir Prus [this message]
2008-02-24 20:08 ` Eli Zaretskii
2008-02-25 19:30 ` Michael Snyder
2008-02-26  0:53   ` Joel Brobecker
2008-03-10 20:43 ` Daniel Jacobowitz
2008-03-10 20:57   ` Vladimir Prus
2008-03-13 12:22     ` Daniel Jacobowitz
2008-03-13 13:19       ` Vladimir Prus

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=200802241750.41264.vladimir@codesourcery.com \
    --to=vladimir@codesourcery.com \
    --cc=gdb-patches@sources.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