This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Windows]Fix a bug which cause GDB.exe assert when try to run the inferior


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]