From 5ffb9207d09aa0e76d696b7d731c6df06a5889e5 Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Thu, 26 Jun 2008 15:10:48 +0000 Subject: [PATCH] * 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. --- gdb/ChangeLog | 7 +++++ gdb/mi/mi-main.c | 4 +-- gdb/target.c | 66 +++++++++++++++++++++++++++++++++++++++ gdb/target.h | 5 +++ gdb/testsuite/gdb.mi/mi-async.exp | 2 +- 5 files changed, 81 insertions(+), 3 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 868989ff16..24d6b75c1b 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2008-06-26 Vladimir Prus + + * 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 Fix a memory leak found by Hui Zhu . diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c index 5d90c75fdb..40e6cf548f 100644 --- a/gdb/mi/mi-main.c +++ b/gdb/mi/mi-main.c @@ -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 (¤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."); diff --git a/gdb/target.c b/gdb/target.c index 6b009a8e76..b2f7be7f7f 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -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 diff --git a/gdb/target.h b/gdb/target.h index 902d4283de..9641f0d62c 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -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, diff --git a/gdb/testsuite/gdb.mi/mi-async.exp b/gdb/testsuite/gdb.mi/mi-async.exp index 9ac91fd724..a7306988d9 100644 --- a/gdb/testsuite/gdb.mi/mi-async.exp +++ b/gdb/testsuite/gdb.mi/mi-async.exp @@ -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 -- 2.11.0