Subject: bug#6500: closed (Re: rm 8.1)

From: [email-masked] (GNU bug Tracking System)
Date: Fri, 25 Jun 2010 05:18:02 +0000

Your bug report

#6500: rm 8.1

which was filed against the coreutils package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
6500: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=6500
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: rm 8.1
From: Jim Meyering <[email-masked]>
To: Brad <[email-masked]>
Cc: [email-masked], [email-masked]
Date: Fri, 25 Jun 2010 07:17:15 +0200
List-Id: <debbugs-submit.debbugs.gnu.org>

Brad wrote:
> Hi Jim:
>
> After learning a little more about the debugger I was able to solve
> the problem.

Good.

> It is clear that the option test is not failing. However only one of
> three tests are being run because the code is linking to the new
> glibc. Therefore the program is calling the fts_open function defined

Think of this as a warning about your compiler and linker options.

> in glibc-2.11.2/io/fts.c rather than lib/fts.c (which does three
> options checks).
>
> 	/* Options check. */
> 	if (options & ~FTS_OPTIONMASK) {
> 		__set_errno (EINVAL);
> 		return (NULL);
> 	}
>
> 	/* Allocate/initialize the stream */
> 	if ((sp = malloc((u_int)sizeof(FTS))) == NULL)
> 		return (NULL);
>
> So the code is failing at the subsequent call to malloc. A
> segmentation fault is occurring because the glibc version of fts_open
> is incompatible with the new coreutils.
>
> I fixed this on my system by redefining fts_open() as
> _fts_open(). That way there is no pollution of the namespace.

Be careful.  That may well be insufficient,
in merely papering over the most apparent problem.

> Here are the diffs:
...
> I think that's it. It's probably not a good idea to redefine a
> function that's already defined in a linked library.

Actually, that's fine.

> The behavior is
> undefined in C because it depends upon the linkage order that is
> determined by the compiler.

This is the problem.
Don't link the C library (-lc) before a projects' own library
(lib/libcoreutils.a).

I'm marking this bug as resolved, but you're welcome
to reply if you have anything to add.

Subject: Re: rm 8.1
From: Jim Meyering <[email-masked]>
To: Brad <[email-masked]>
Cc: [email-masked]
Date: Wed, 23 Jun 2010 21:58:14 +0200
List-Id: <debbugs-submit.debbugs.gnu.org>

Brad wrote:
> Hi Jim:

Hi Brad,

I've Cc'd the bug-reporting address.
It's better to report problems to that address than to my personal one.

> Are you sure this is fixed?

How could I be sure it is fixed, considering
that this is the first I've heard of this failure?

> I get these errors:
> rm: ../../coreutils-8.5/lib/xfts.c:41: xfts_open: Assertion
> (*__errno_location ()) != 22' failed.
> Aborted
>
> chmod: ../../coreutils-8.5/lib/xfts.c:41: xfts_open: Assertion
> (*__errno_location ()) != 22' failed.
> Aborted
>
> du: ../../coreutils-8.5/lib/xfts.c:41: xfts_open: Assertion
> (*__errno_location ()) != 22' failed.
> Aborted
>
> It appears that the call to fts_open is failing but I do not
> understand the reason. All of the other utilities that don't use this
> function are still working fine.
>
> The system is running kernel 2.6.34 and the binaries are linked to
> glibc-2.11.2. I had to use slackware binaries for rm and chmod in
> order to get the system to boot. Clearly this is not right.
>
> If you have any ideas what might be wrong I would be glad to help fix
> this. I look forward to your input.

You seem to be hitting this assertion:

FTS *
xfts_open (char * const *argv, int options,
           int (*compar) (const FTSENT **, const FTSENT **))
{
  FTS *fts = fts_open (argv, options | FTS_CWDFD, compar);
  if (fts == NULL)
    {
      /* This can fail in two ways: out of memory or with errno==EINVAL,
         which indicates it was called with invalid bit_flags.  */
      assert (errno != EINVAL);
      xalloc_die ();
    }

  return fts;
}

Did you build the failing rm yourself?
>From unmodified sources?
If so, please provide the precise ./configure and "make"
commands you used and tell us more about your system.

As far as I know, this is the first report of such a problem,
so I suspect something about your environment is at least "unusual".

There are only a few ways fts_open can return with errno
set to EINVAL, and none should be possible from coreutils programs:

FTS *
fts_open (char * const *argv,
          register int options,
          int (*compar) (FTSENT const **, FTSENT const **))
{
        register FTS *sp;
        register FTSENT *p, *root;
        register size_t nitems;
        FTSENT *parent = NULL;
        FTSENT *tmp = NULL;     /* pacify gcc */
        bool defer_stat;

        /* Options check. */
        if (options & ~FTS_OPTIONMASK) {
                __set_errno (EINVAL);
                return (NULL);
        }
        if ((options & FTS_NOCHDIR) && (options & FTS_CWDFD)) {
                __set_errno (EINVAL);
                return (NULL);
        }
        if ( ! (options & (FTS_LOGICAL | FTS_PHYSICAL))) {
                __set_errno (EINVAL);
                return (NULL);
        }

Can you debug it and tell us which one it is?