[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#355109: libc6.1: ia64 build failure for coreutils

tags 355109 + patch

> pwd: ../sysdeps/unix/sysv/linux/getcwd.c:130: __getcwd: Assertion `__libc_errno != 34 || buf != ((void *)0) || size != 0' failed.
> pwd: /build/buildd/coreutils-5.94/build-tree/coreutils-5.94/tests/misc/pwd.tmp/25528/zzzzzzzzzzzzzzzzzzzzzzzzzzzzz[...]

> The above is part of the build tests. For some reason this assertion
> occurs on ia64, but every other architecture builds fine, suggesting a
> problem in the ia64 toolchain.

Actually, it will occur on any machine that has PAGE_SIZE >> PATH_MAX

Possible workarounds for coreutils:  Use a path of more than 16384
bytes in length for the test, rather than just more than 4096. :-)

For glibc:  The assertion is bogus.  In fact, the path in question from
this test is more than PATH_MAX bytes in length.  Because
PAGE_SIZE==PATH_MAX, sys_getcwd returns ENAMETOOLONG (since it can't
construct the path in the buffer it's using internally), while ia64 has
enough room to build a path (up to 16K), but not enough room to return
it in the malloced buffer from getcwd(3).

The correct solution is, of course, to copy the code from the readlink
loop immediately below the assert to realloc until it fits.  OTOH,
the diff below makes it behave the same as it does today on all
machines.  (Return NULL when the cwd path is > PATH_MAX bytes.)


--- glibc-2.3.6/build-tree/glibc-2.3.6/sysdeps/unix/sysv/linux/getcwd.c.old	2003-09-19 19:05:49.000000000 -0600
+++ glibc-2.3.6/build-tree/glibc-2.3.6/sysdeps/unix/sysv/linux/getcwd.c	2003-09-19 	2006-03-23 16:11:04.000000000 -0700
@@ -124,10 +124,12 @@
-      /* It should never happen that the `getcwd' syscall failed because
-	 the buffer is too small if we allocated the buffer ourselves
-	 large enough.  */
-      assert (errno != ERANGE || buf != NULL || size != 0);
+      /* It is possible that the `getcwd' syscall failed because
+	 the buffer is too small even though we allocaed MAX_PATH
+	 bytes.  If PAGE_SIZE != PATH_MAX, then we can get back ERANGE
+	 instead of ENAMETOOLONG in this case. */
+      assert ((errno != ERANGE && errno != ENAMETOOLONG) ||
+	      buf != NULL || size != 0);
 #  ifndef NO_ALLOCATION
       if (buf == NULL)

Reply to: