From 92ffd475192030a46a6046177c732372b4dadad5 Mon Sep 17 00:00:00 2001 From: Paul Carroll Date: Tue, 14 Nov 2017 17:37:37 -0500 Subject: [PATCH] Fix 'xfered>0' assertion in target.c for remote connection We have a customer who is using a Corelis gdb server to connect to gdb. Occasionally, the gdb server will send a 0-byte block of memory for a read. When this happens, gdb gives an assertion from target.c: internal-error: target_xfer_partial: Assertion `*xfered_len > 0' failed. This problem is almost identical to that fixed in https://sourceware.org/ml/gdb-patches/2014-02/msg00636.html In this case, remote.c needs to be modified to return TARGET_XFER_EOF instead of TARGET_XFER_OK or TARGET_XFER_UNAVAILABLE when 0 bytes are transferred. gdb/ChangeLog: PR gdb/22388 * remote.c (remote_write_bytes_aux, remote_read_bytes_1, remote_read_bytes, remote_write_qxfer, remote_xfer_partial): Return TARGET_XFER_EOF if size of returned data is 0. --- gdb/ChangeLog | 7 +++++++ gdb/remote.c | 11 ++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 9a22ce7..6afec28 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2017-11-14 Paul Carroll + + PR gdb/22388 + * remote.c (remote_write_bytes_aux, remote_read_bytes_1, + remote_read_bytes, remote_write_qxfer, remote_xfer_partial): + Return TARGET_XFER_EOF if size of returned data is 0. + 2017-11-14 Simon Marchi * Makefile.in (SUBDIR_UNITTESTS_SRCS): Add diff --git a/gdb/remote.c b/gdb/remote.c index c653562..62ac055 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -8264,7 +8264,7 @@ remote_write_bytes_aux (const char *header, CORE_ADDR memaddr, /* Return UNITS_WRITTEN, not TODO_UNITS, in case escape chars caused us to send fewer units than we'd planned. */ *xfered_len_units = (ULONGEST) units_written; - return TARGET_XFER_OK; + return (*xfered_len_units != 0) ? TARGET_XFER_OK : TARGET_XFER_EOF; } /* Write memory data directly to the remote machine. @@ -8358,7 +8358,7 @@ remote_read_bytes_1 (CORE_ADDR memaddr, gdb_byte *myaddr, ULONGEST len_units, decoded_bytes = hex2bin (p, myaddr, todo_units * unit_size); /* Return what we have. Let higher layers handle partial reads. */ *xfered_len_units = (ULONGEST) (decoded_bytes / unit_size); - return TARGET_XFER_OK; + return (*xfered_len_units != 0) ? TARGET_XFER_OK : TARGET_XFER_EOF; } /* Using the set of read-only target sections of remote, read live @@ -8461,7 +8461,8 @@ remote_read_bytes (struct target_ops *ops, CORE_ADDR memaddr, /* No use trying further, we know some memory starting at MEMADDR isn't available. */ *xfered_len = len; - return TARGET_XFER_UNAVAILABLE; + return (*xfered_len != 0) ? + TARGET_XFER_UNAVAILABLE : TARGET_XFER_EOF; } } @@ -10386,7 +10387,7 @@ remote_write_qxfer (struct target_ops *ops, const char *object_name, unpack_varlen_hex (rs->buf, &n); *xfered_len = n; - return TARGET_XFER_OK; + return (*xfered_len != 0) ? TARGET_XFER_OK : TARGET_XFER_EOF; } /* Read OBJECT_NAME/ANNEX from the remote target using a qXfer packet. @@ -10687,7 +10688,7 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object, strcpy ((char *) readbuf, rs->buf); *xfered_len = strlen ((char *) readbuf); - return TARGET_XFER_OK; + return (*xfered_len != 0) ? TARGET_XFER_OK : TARGET_XFER_EOF; } /* Implementation of to_get_memory_xfer_limit. */ -- 2.7.4