This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[Windows]Fix a bug which cause GDB.exe assert when try to run the inferior
- From: asmwarrior <asmwarrior at gmail dot com>
- To: gdb-patches at sourceware dot org
- Cc: Yao Qi <qiyaoltc at gmail dot com>
- Date: Thu, 20 Feb 2014 22:35:20 +0800
- Subject: [Windows]Fix a bug which cause GDB.exe assert when try to run the inferior
- Authentication-results: sourceware.org; auth=none
I see GDB.exe(build from GIT HEAD) can't run any inferior now, it just stops and assert. See the log:
[debug]Starting program:
E:\code\lex\lessons\001_upn_calculator\bin\Debug\test.exe
[debug]../../binutils-gdb/gdb/target.c:1483: internal-error:
target_xfer_partial: Assertion `*xfered_len > 0' failed.
[debug]A problem internal to GDB has been detected,
[debug]further debugging may prove unreliable.
[debug]This application has requested the Runtime to terminate it in an
unusual way.
[debug]Please contact the application's support team for more information.
I found that the assert is here:
/* Check implementations of to_xfer_partial update *XFERED_LEN
properly. Do assertion after printing debug messages, so that we
can find more clues on assertion failure from debugging messages. */
if (retval == TARGET_XFER_OK || retval == TARGET_XFER_E_UNAVAILABLE)
gdb_assert (*xfered_len > 0);
Track down, I found that it is a bug introduced in this commit:
SHA-1: 9b409511d07fe375284701af34909fb539029caf
2014-02-11 Yao Qi <yao@codesourcery.com>
* Return target_xfer_status in to_xfer_partial
This patch does the conversion of to_xfer_partial from
LONGEST (*to_xfer_partial) (struct target_ops *ops,
enum target_object object, const char *annex,
gdb_byte *readbuf, const gdb_byte *writebuf,
ULONGEST offset, ULONGEST len);
to
enum target_xfer_status (*to_xfer_partial) (struct target_ops *ops,
enum target_object object, const char *annex,
gdb_byte *readbuf, const gdb_byte *writebuf,
ULONGEST offset, ULONGEST len, ULONGEST *xfered_len);
It changes to_xfer_partial return the transfer status and the transfered
length by *XFERED_LEN. Generally, the return status has three stats,
- TARGET_XFER_OK,
- TARGET_XFER_EOF,
- TARGET_XFER_E_XXXX,
Especially the change on windows-nat.c
@@ -2536,27 +2538,30 @@ windows_xfer_shared_libraries (struct target_ops *ops,
}
obstack_free (&obstack, NULL);
- return len;
+ *xfered_len = (ULONGEST) len;
+ return TARGET_XFER_OK;
}
The original code return len(len could be 0), but the new code just return TARGET_XFER_OK.
If len is 0, it should return TARGET_XFER_EOF(it is 0 in enum target_xfer_status declaration.
So, a patch below is confirmed to fix the assert issue, an obvious fix, right?
gdb/windows-nat.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index a570a1a..b76d94d 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -2480,7 +2480,7 @@ windows_xfer_shared_libraries (struct target_ops *ops,
obstack_free (&obstack, NULL);
*xfered_len = (ULONGEST) len;
- return TARGET_XFER_OK;
+ return len ? TARGET_XFER_OK : TARGET_XFER_EOF;
}
static enum target_xfer_status
Thanks Yao for the hint, so cc to him.
Yuanhui Zhang