* target.c (target_read_until_error): New.
authorVladimir Prus <vladimir@codesourcery.com>
Thu, 26 Jun 2008 15:10:48 +0000 (15:10 +0000)
committerVladimir Prus <vladimir@codesourcery.com>
Thu, 26 Jun 2008 15:10:48 +0000 (15:10 +0000)
        * target.h (target_read_until_error): Declare.
        * mi/mi-main.c (mi_cmd_data_read_memory): Use
        target_read_until_error.

gdb/ChangeLog
gdb/mi/mi-main.c
gdb/target.c
gdb/target.h
gdb/testsuite/gdb.mi/mi-async.exp

index 868989ff164605e36b3fe2250356b25f46c17ed9..24d6b75c1b2b2c3dfe3440df9c93e6e35ee64fc2 100644 (file)
@@ -1,3 +1,10 @@
+2008-06-26  Vladimir Prus  <vladimir@codesourcery.com>
+
+       * target.c (target_read_until_error): New.
+        * target.h (target_read_until_error): Declare.
+        * mi/mi-main.c (mi_cmd_data_read_memory): Use
+        target_read_until_error.
+
 2008-06-25  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        Fix a memory leak found by Hui Zhu <teawater@gmail.com>.
index 5d90c75fdbfc5b2e19bdde489fdcd0f78bc3c49e..40e6cf548f4129a4f431b69b992ca3c961355bda 100644 (file)
@@ -782,8 +782,8 @@ mi_cmd_data_read_memory (char *command, char **argv, int argc)
   mbuf = xcalloc (total_bytes, 1);
   make_cleanup (xfree, mbuf);
 
-  nr_bytes = target_read (&current_target, TARGET_OBJECT_MEMORY, NULL,
-                         mbuf, addr, total_bytes);
+  nr_bytes = target_read_until_error (&current_target, TARGET_OBJECT_MEMORY, 
+                                     NULL, mbuf, addr, total_bytes);
   if (nr_bytes <= 0)
     error ("Unable to read memory.");
 
index 6b009a8e76cfb1322a9a0c28b44d2aee394dbfb7..b2f7be7f7f7bd74a82b611d60db9afad9e78db8d 100644 (file)
@@ -1451,6 +1451,72 @@ target_read (struct target_ops *ops,
   return len;
 }
 
+LONGEST
+target_read_until_error (struct target_ops *ops,
+                        enum target_object object,
+                        const char *annex, gdb_byte *buf,
+                        ULONGEST offset, LONGEST len)
+{
+  LONGEST xfered = 0;
+  while (xfered < len)
+    {
+      LONGEST xfer = target_read_partial (ops, object, annex,
+                                         (gdb_byte *) buf + xfered,
+                                         offset + xfered, len - xfered);
+      /* Call an observer, notifying them of the xfer progress?  */
+      if (xfer == 0)
+       return xfered;
+      if (xfer < 0)
+       {
+         /* We've got an error.  Try to read in smaller blocks.  */
+         ULONGEST start = offset + xfered;
+         ULONGEST remaining = len - xfered;
+         ULONGEST half;
+
+         /* If an attempt was made to read a random memory address,
+            it's likely that the very first byte is not accessible.
+            Try reading the first byte, to avoid doing log N tries
+            below.  */
+         xfer = target_read_partial (ops, object, annex, 
+                                     (gdb_byte *) buf + xfered, start, 1);
+         if (xfer <= 0)
+           return xfered;
+         start += 1;
+         remaining -= 1;
+         half = remaining/2;
+         
+         while (half > 0)
+           {
+             xfer = target_read_partial (ops, object, annex,
+                                         (gdb_byte *) buf + xfered,
+                                         start, half);
+             if (xfer == 0)
+               return xfered;
+             if (xfer < 0)
+               {
+                 remaining = half;               
+               }
+             else
+               {
+                 /* We have successfully read the first half.  So, the
+                    error must be in the second half.  Adjust start and
+                    remaining to point at the second half.  */
+                 xfered += xfer;
+                 start += xfer;
+                 remaining -= xfer;
+               }
+             half = remaining/2;
+           }
+
+         return xfered;
+       }
+      xfered += xfer;
+      QUIT;
+    }
+  return len;
+}
+
+
 /* An alternative to target_write with progress callbacks.  */
 
 LONGEST
index 902d4283de59143cb15405f9d1f263dfd6e2b889..9641f0d62c872407300c40f98cc721028155de09 100644 (file)
@@ -230,6 +230,11 @@ extern LONGEST target_read (struct target_ops *ops,
                            const char *annex, gdb_byte *buf,
                            ULONGEST offset, LONGEST len);
 
+extern LONGEST target_read_until_error (struct target_ops *ops,
+                                       enum target_object object,
+                                       const char *annex, gdb_byte *buf,
+                                       ULONGEST offset, LONGEST len);
+  
 extern LONGEST target_write (struct target_ops *ops,
                             enum target_object object,
                             const char *annex, const gdb_byte *buf,
index 9ac91fd72408388cacd6bd2fa77b0cea01174c87..a7306988d91c5542dd4e22f3d3b672673bbfa2d3 100644 (file)
@@ -27,7 +27,7 @@ if { !([isnative] && [istarget *-linux*]) \
 
 # The plan is for async mode to become the default but toggle for now.
 set saved_gdbflags $GDBFLAGS
-set GDBFLAGS [concat $GDBFLAGS " -ex \"maint set linux-async on\""]
+#set GDBFLAGS [concat $GDBFLAGS " -ex \"maint set linux-async on\""]
 
 load_lib mi-support.exp