* target.h (target_read_until_error): Declare.
* mi/mi-main.c (mi_cmd_data_read_memory): Use
target_read_until_error.
+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>.
mbuf = xcalloc (total_bytes, 1);
make_cleanup (xfree, mbuf);
- nr_bytes = target_read (¤t_target, TARGET_OBJECT_MEMORY, NULL,
- mbuf, addr, total_bytes);
+ nr_bytes = target_read_until_error (¤t_target, TARGET_OBJECT_MEMORY,
+ NULL, mbuf, addr, total_bytes);
if (nr_bytes <= 0)
error ("Unable to read memory.");
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
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,
# 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