GNU bug report logs - #6500
rm 8.1

Previous Next

Package: coreutils;

Reported by: Jim Meyering <jim <at> meyering.net>

Date: Wed, 23 Jun 2010 19:59:02 UTC

Severity: normal

Done: Jim Meyering <jim <at> meyering.net>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 6500 in the body.
You can then email your comments to 6500 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org:
bug#6500; Package coreutils. (Wed, 23 Jun 2010 19:59:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Jim Meyering <jim <at> meyering.net>:
New bug report received and forwarded. Copy sent to bug-coreutils <at> gnu.org. (Wed, 23 Jun 2010 19:59:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Jim Meyering <jim <at> meyering.net>
To: Brad <b.mells <at> outwild.net>
Cc: bug-coreutils <at> gnu.org
Subject: Re: rm 8.1
Date: Wed, 23 Jun 2010 21:58:14 +0200
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?




Information forwarded to owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org:
bug#6500; Package coreutils. (Wed, 23 Jun 2010 20:58:02 GMT) Full text and rfc822 format available.

Message #8 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Brad <b.mells <at> outwild.net>
To: Jim Meyering <jim <at> meyering.net>
Cc: bug-coreutils <at> gnu.org, Brad <b.mells <at> outwild.net>
Subject: Re: rm 8.1
Date: Wed, 23 Jun 2010 13:52:51 -0700
Thanks for your help Jim. I tried to debug the program by running gdb. 
I'm not sure if the backtrace has the information you need.

GNU gdb (GDB) 7.1
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
<http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb) file src/rm
Reading symbols from /home/brad/tools/core_boot/src/rm...(no debugging 
symbols found)...done.
(gdb) set args test
(gdb) run
Starting program: /home/brad/tools/core_boot/src/rm test
rm: ../../coreutils-8.5/lib/xfts.c:41: xfts_open: Assertion 
`(*__errno_location ()) != 22' failed.

Program received signal SIGABRT, Aborted.
0x00007ffff7abb035 in *__GI_raise (sig=<value optimized out>) at 
../nptl/sysdeps/unix/sysv/linux/raise.c:64
64        return INLINE_SYSCALL (tgkill, 3, pid, selftid, sig);
(gdb) bt
#0  0x00007ffff7abb035 in *__GI_raise (sig=<value optimized out>) at 
../nptl/sysdeps/unix/sysv/linux/raise.c:64
#1  0x00007ffff7abc460 in *__GI_abort () at abort.c:92
#2  0x00007ffff7ab4171 in *__GI___assert_fail (assertion=0x407def 
"(*__errno_location ()) != 22",
    file=<value optimized out>, line=41, function=0x407e0c "xfts_open") 
at assert.c:81
#3  0x0000000000406179 in xfts_open ()
#4  0x00000000004031dc in rm ()
#5  0x00000000004022d2 in main ()


I am not an expert at using gdb. Please let me know if you have any 
suggestions to get more information.

My environment is somewhat unusual. I am compiling a new system in 
/bootstrap against the updated glibc. The new system boots up with 
glibc-2.11.2. The development environment uses the older glibc-2.10.1. 
So I need to adjust the compiler spec file to ensure that the right 
linkage is done.

The sources were not modified. Everything compiles fine but the 
xfts_open is not working.


Here are the options to configure:

../coreutils-8.5/configure --prefix=/bootstrap --without-gmp 
CFLAGS='-specs=/bootstrap/gcc.specs' LDFLAGS=-Wl,-rpath,/bootstrap/lib,-lc

Here is how I adjusted the specs:

diff built-in.specs /bootstrap/gcc.specs
51c51
< %{!static:--eh-frame-hdr} %{!m32:-m elf_x86_64} %{m32:-m elf_i386} 
--hash-style=both   %{shared:-shared}   %{!shared:     %{!static: 
%{rdynamic:-export-dynamic} 
%{m32:%{!dynamic-linker:-dynamic-linker %{muclibc:%{mglibc:%e-mglibc and 
-muclibc used together}/lib/ld-uClibc.so.0;:/lib32/ld-linux.so.2}}} 
  %{!m32:%{!dynamic-linker:-dynamic-linker %{muclibc:%{mglibc:%e-mglibc 
and -muclibc used 
together}/lib/ld64-uClibc.so.0;:/lib/ld-linux-x86-64.so.2}}}} 
%{static:-static}}
---
> %{!static:--eh-frame-hdr} %{!m32:-m elf_x86_64} %{m32:-m elf_i386} 
--hash-style=both   %{shared:-shared}   %{!shared:     %{!static: 
%{rdynamic:-export-dynamic} 
%{m32:%{!dynamic-linker:-dynamic-linker %{muclibc:%{mglibc:%e-mglibc and 
-muclibc used together}/lib/ld-uClibc.so.0;:/lib32/ld-linux.so.2}}} 
  %{!m32:%{!dynamic-linker:-dynamic-linker %{muclibc:%{mglibc:%e-mglibc 
and -muclibc used 
together}/lib/ld64-uClibc.so.0;:/bootstrap/lib/ld-linux-x86-64.so.2}}}} 
    %{static:-static}}
54c54
< %{pthread:-lpthread}    %{shared:-lc}    %{!shared:%{mieee-fp:-lieee} 
%{profile:-lc_p}%{!profile:-lc}}
---
> %{pthread:-lpthread}    %{shared:-L/bootstrap/lib -lc} 
%{!shared:%{mieee-fp:-lieee} %{profile:-lc_p}%{!profile:-lc}}


Please let me know if you need more information. I can always modify the 
sources to gain useful debugging data. Hopefully you have a better idea.



Jim Meyering wrote:
> 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?
> 

-- 
Brad Mells
Quantum Harmonics
889 Mowry Ave #86
Fremont CA 94536

619.808.2359





Information forwarded to owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org:
bug#6500; Package coreutils. (Wed, 23 Jun 2010 21:22:01 GMT) Full text and rfc822 format available.

Message #11 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Jim Meyering <jim <at> meyering.net>
To: Brad <b.mells <at> outwild.net>
Cc: bug-coreutils <at> gnu.org
Subject: Re: rm 8.1
Date: Wed, 23 Jun 2010 23:13:06 +0200
Brad wrote:
> Thanks for your help Jim. I tried to debug the program by running
> gdb. I'm not sure if the backtrace has the information you need.
...
> Please let me know if you have any
> suggestions to get more information.

Thanks for the details.
Here's how to get more:

First, recompile at least lib/fts.c using with -g added to CFLAGS,
and relink say rm.

Create a tiny tree in src/ that we'll remove:

  cd src # if you weren't there already
  mkdir -p a/b/c/d

Then run gdb on rm:

  gdb rm

set a breakpoint in fts_open (not xfts_open):

  b fts_open

run rm on that tree:

  run -rf a/b/c/d

Now, you'll see that gdb has stopped in fts_open.
gdb's output will show the values of the function parameters,
including the "options" variable.
That's probably all I need, but just to be sure, continue
a little further, and single step through it using "n" (for "next")
until it returns:

One of the following three return statements should trigger:

        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);
        }

Then show us the output of the above commands.

Thanks.




Information forwarded to owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org:
bug#6500; Package coreutils. (Wed, 23 Jun 2010 23:38:02 GMT) Full text and rfc822 format available.

Message #14 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Brad <bmells <at> harmonicskintones.com>
To: Jim Meyering <jim <at> meyering.net>
Cc: bug-coreutils <at> gnu.org, Brad <b.mells <at> outwild.net>
Subject: Re: rm 8.1
Date: Wed, 23 Jun 2010 14:34:15 -0700
Thanks Jim!

I knew you would know what to do. Please tell me what this all means. 
Here is the output you need:

GNU gdb (GDB) 7.1
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
<http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb) file rm
Reading symbols from /home/brad/tools/core_debug/src/rm...done.
(gdb) b fts_open
Breakpoint 1 at 0x4015c8
(gdb) run -rf a/b/c/d
Starting program: /home/brad/tools/core_debug/src/rm -rf a/b/c/d

Breakpoint 1, fts_open (argv=0x7fffffffed08, options=536, compar=0) at 
fts.c:92
92      {
(gdb) n
100             if (options & ~FTS_OPTIONMASK) {
(gdb) n
101                     __set_errno (EINVAL);
(gdb) n
201     }
(gdb) n
xfts_open (argv=0x7fffffffed08, options=536, compar=0) at 
../../coreutils-8.5/lib/xfts.c:37
37        if (fts == NULL)
(gdb) n
41            assert (errno != EINVAL);
(gdb) n
rm: ../../coreutils-8.5/lib/xfts.c:41: xfts_open: Assertion 
`(*__errno_location ()) != 22' failed.

Program received signal SIGABRT, Aborted.
0x00007ffff7abb035 in *__GI_raise (sig=<value optimized out>) at 
../nptl/sysdeps/unix/sysv/linux/raise.c:64
64        return INLINE_SYSCALL (tgkill, 3, pid, selftid, sig);
(gdb) n

Program terminated with signal SIGABRT, Aborted.
The program no longer exists.



Jim Meyering wrote:
> Brad wrote:
>> Thanks for your help Jim. I tried to debug the program by running
>> gdb. I'm not sure if the backtrace has the information you need.
> ...
>> Please let me know if you have any
>> suggestions to get more information.
> 
> Thanks for the details.
> Here's how to get more:
> 
> First, recompile at least lib/fts.c using with -g added to CFLAGS,
> and relink say rm.
> 
> Create a tiny tree in src/ that we'll remove:
> 
>   cd src # if you weren't there already
>   mkdir -p a/b/c/d
> 
> Then run gdb on rm:
> 
>   gdb rm
> 
> set a breakpoint in fts_open (not xfts_open):
> 
>   b fts_open
> 
> run rm on that tree:
> 
>   run -rf a/b/c/d
> 
> Now, you'll see that gdb has stopped in fts_open.
> gdb's output will show the values of the function parameters,
> including the "options" variable.
> That's probably all I need, but just to be sure, continue
> a little further, and single step through it using "n" (for "next")
> until it returns:
> 
> One of the following three return statements should trigger:
> 
>         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);
>         }
> 
> Then show us the output of the above commands.
> 
> Thanks.
> 

-- 
Brad Mells
Quantum Harmonics
889 Mowry Ave #86
Fremont CA 94536

619.808.2359





Information forwarded to owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org:
bug#6500; Package coreutils. (Thu, 24 Jun 2010 05:20:03 GMT) Full text and rfc822 format available.

Message #17 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Jim Meyering <jim <at> meyering.net>
To: Brad <bmells <at> harmonicskintones.com>
Cc: bug-coreutils <at> gnu.org, Brad <b.mells <at> outwild.net>
Subject: Re: rm 8.1
Date: Thu, 24 Jun 2010 07:17:13 +0200
Brad wrote:
...
> (gdb) run -rf a/b/c/d
> Starting program: /home/brad/tools/core_debug/src/rm -rf a/b/c/d
>
> Breakpoint 1, fts_open (argv=0x7fffffffed08, options=536, compar=0) at
> fts.c:92
> 92      {
> (gdb) n
> 100             if (options & ~FTS_OPTIONMASK) {
> (gdb) n
> 101                     __set_errno (EINVAL);
> (gdb) n
> 201     }
> (gdb) n
> xfts_open (argv=0x7fffffffed08, options=536, compar=0) at
> ../../coreutils-8.5/lib/xfts.c:37

Thanks.  that "options" value is 0x218, which makes sense:

    # define FTS_NOSTAT     0x0008          /* don't get stat info */
    # define FTS_PHYSICAL   0x0010          /* physical walk */
    # define FTS_CWDFD      0x0200

      int bit_flags = (FTS_CWDFD | FTS_NOSTAT | FTS_PHYSICAL);
      ...
      FTS *fts = xfts_open (file, bit_flags, NULL);

The other value in that comparison should come from fts_.h:

    # define FTS_OPTIONMASK 0x07ff          /* valid user option mask */

But is that actually the value used on your system?

To find out, do this:

    cd lib
    rm fts.o
    make AM_CFLAGS='-E -dD' fts.o

That is a hack to obtain C-preprocessed sources.
Rename the file to have a sensible suffix, and so it
doesn't interfere with a subsequent build:

    mv fts.o fts.i

In my copy, I see this:

        if (options & ~0x07ff) {
                (*__errno_location ()) = (22);
                return (((void *)0));
        }

If you see the same thing, then suspect that your compiler is at fault.
In that case, there's one more thing you can do:

Repeat the steps you performed above, then run this command right after
hitting the breakpoint, and tell us what it prints:

  print options & ~0x07ff




Information forwarded to owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org:
bug#6500; Package coreutils. (Thu, 24 Jun 2010 17:17:02 GMT) Full text and rfc822 format available.

Message #20 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Brad <b.mells <at> outwild.net>
To: Jim Meyering <jim <at> meyering.net>
Cc: bug-coreutils <at> gnu.org, Brad <b.mells <at> outwild.net>
Subject: Re: rm 8.1
Date: Thu, 24 Jun 2010 10:16:53 -0700
Hi Jim, my copy of fts.i looks the same as yours. Here is the additional 
gdb output:

### begin gdb ###
Starting program: /home/brad/tools/core_debug/src/rm -rf a/b/c/d

Breakpoint 1, fts_open (argv=0x7fffffffed08, options=536, compar=0) at 
fts.c:92
92      {
(gdb) print options & ~0x07ff
$1 = 0

### end gdb ###

Please tell me what this means. I knew the bit flags from function rm in 
src/remove.c:

      int bit_flags = (FTS_CWDFD
                       | FTS_NOSTAT
                       | FTS_PHYSICAL);

      if (x->one_file_system)
        bit_flags |= FTS_XDEV;

      FTS *fts = xfts_open (file, bit_flags, NULL);


and of course the option mask from lib/fts_.h:

# define FTS_OPTIONMASK 0x07ff          /* valid user option mask */

But how do you read this from the gdb output?

Thanks for your help. I really appreciate your prompt attention to this 
matter. Please let me know if there is anything else you need me to do.


Jim Meyering wrote:
> Brad wrote:
> ...
>> (gdb) run -rf a/b/c/d
>> Starting program: /home/brad/tools/core_debug/src/rm -rf a/b/c/d
>>
>> Breakpoint 1, fts_open (argv=0x7fffffffed08, options=536, compar=0) at
>> fts.c:92
>> 92      {
>> (gdb) n
>> 100             if (options & ~FTS_OPTIONMASK) {
>> (gdb) n
>> 101                     __set_errno (EINVAL);
>> (gdb) n
>> 201     }
>> (gdb) n
>> xfts_open (argv=0x7fffffffed08, options=536, compar=0) at
>> ../../coreutils-8.5/lib/xfts.c:37
> 
> Thanks.  that "options" value is 0x218, which makes sense:
> 
>     # define FTS_NOSTAT     0x0008          /* don't get stat info */
>     # define FTS_PHYSICAL   0x0010          /* physical walk */
>     # define FTS_CWDFD      0x0200
> 
>       int bit_flags = (FTS_CWDFD | FTS_NOSTAT | FTS_PHYSICAL);
>       ...
>       FTS *fts = xfts_open (file, bit_flags, NULL);
> 
> The other value in that comparison should come from fts_.h:
> 
>     # define FTS_OPTIONMASK 0x07ff          /* valid user option mask */
> 
> But is that actually the value used on your system?
> 
> To find out, do this:
> 
>     cd lib
>     rm fts.o
>     make AM_CFLAGS='-E -dD' fts.o
> 
> That is a hack to obtain C-preprocessed sources.
> Rename the file to have a sensible suffix, and so it
> doesn't interfere with a subsequent build:
> 
>     mv fts.o fts.i
> 
> In my copy, I see this:
> 
>         if (options & ~0x07ff) {
>                 (*__errno_location ()) = (22);
>                 return (((void *)0));
>         }
> 
> If you see the same thing, then suspect that your compiler is at fault.
> In that case, there's one more thing you can do:
> 
> Repeat the steps you performed above, then run this command right after
> hitting the breakpoint, and tell us what it prints:
> 
>   print options & ~0x07ff
> 

-- 
Brad Mells
Quantum Harmonics
889 Mowry Ave #86
Fremont CA 94536

619.808.2359





Information forwarded to owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org:
bug#6500; Package coreutils. (Thu, 24 Jun 2010 21:56:02 GMT) Full text and rfc822 format available.

Message #23 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Brad <b.mells <at> outwild.net>
To: Brad <b.mells <at> outwild.net>
Cc: bug-coreutils <at> gnu.org, Jim Meyering <jim <at> meyering.net>
Subject: Re: rm 8.1
Date: Thu, 24 Jun 2010 14:56:19 -0700
Hi Jim:

After learning a little more about the debugger I was able to solve the 
problem.

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 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.

Here are the diffs:

diff fts_.h ../../core_source/lib/fts_.h
254c254
< FTS     *_fts_open (char * const *, int,
---
> FTS     *fts_open (char * const *, int,


diff fts.c ../../core_source/lib/fts.c
362c362
< _fts_open (char * const *argv,
---
> fts_open (char * const *argv,


diff xfts.c ../../core_source/lib/xfts.c
36c36
<   FTS *fts = _fts_open (argv, options | FTS_CWDFD, compar);
---
>   FTS *fts = fts_open (argv, options | FTS_CWDFD, compar);


I think that's it. It's probably not a good idea to redefine a function 
that's already defined in a linked library. The behavior is undefined in 
C because it depends upon the linkage order that is determined by the 
compiler.

I hope this helps. Thank you for all of your savvy guidance.

Best wishes,


Brad


Brad wrote:
> Hi Jim, my copy of fts.i looks the same as yours. Here is the additional 
> gdb output:
> 
> ### begin gdb ###
> Starting program: /home/brad/tools/core_debug/src/rm -rf a/b/c/d
> 
> Breakpoint 1, fts_open (argv=0x7fffffffed08, options=536, compar=0) at 
> fts.c:92
> 92      {
> (gdb) print options & ~0x07ff
> $1 = 0
> 
> ### end gdb ###
> 
> Please tell me what this means. I knew the bit flags from function rm in 
> src/remove.c:
> 
>       int bit_flags = (FTS_CWDFD
>                        | FTS_NOSTAT
>                        | FTS_PHYSICAL);
> 
>       if (x->one_file_system)
>         bit_flags |= FTS_XDEV;
> 
>       FTS *fts = xfts_open (file, bit_flags, NULL);
> 
> 
> and of course the option mask from lib/fts_.h:
> 
> # define FTS_OPTIONMASK 0x07ff          /* valid user option mask */
> 
> But how do you read this from the gdb output?
> 
> Thanks for your help. I really appreciate your prompt attention to this 
> matter. Please let me know if there is anything else you need me to do.
> 
> 
> Jim Meyering wrote:
>> Brad wrote:
>> ...
>>> (gdb) run -rf a/b/c/d
>>> Starting program: /home/brad/tools/core_debug/src/rm -rf a/b/c/d
>>>
>>> Breakpoint 1, fts_open (argv=0x7fffffffed08, options=536, compar=0) at
>>> fts.c:92
>>> 92      {
>>> (gdb) n
>>> 100             if (options & ~FTS_OPTIONMASK) {
>>> (gdb) n
>>> 101                     __set_errno (EINVAL);
>>> (gdb) n
>>> 201     }
>>> (gdb) n
>>> xfts_open (argv=0x7fffffffed08, options=536, compar=0) at
>>> ../../coreutils-8.5/lib/xfts.c:37
>>
>> Thanks.  that "options" value is 0x218, which makes sense:
>>
>>     # define FTS_NOSTAT     0x0008          /* don't get stat info */
>>     # define FTS_PHYSICAL   0x0010          /* physical walk */
>>     # define FTS_CWDFD      0x0200
>>
>>       int bit_flags = (FTS_CWDFD | FTS_NOSTAT | FTS_PHYSICAL);
>>       ...
>>       FTS *fts = xfts_open (file, bit_flags, NULL);
>>
>> The other value in that comparison should come from fts_.h:
>>
>>     # define FTS_OPTIONMASK 0x07ff          /* valid user option mask */
>>
>> But is that actually the value used on your system?
>>
>> To find out, do this:
>>
>>     cd lib
>>     rm fts.o
>>     make AM_CFLAGS='-E -dD' fts.o
>>
>> That is a hack to obtain C-preprocessed sources.
>> Rename the file to have a sensible suffix, and so it
>> doesn't interfere with a subsequent build:
>>
>>     mv fts.o fts.i
>>
>> In my copy, I see this:
>>
>>         if (options & ~0x07ff) {
>>                 (*__errno_location ()) = (22);
>>                 return (((void *)0));
>>         }
>>
>> If you see the same thing, then suspect that your compiler is at fault.
>> In that case, there's one more thing you can do:
>>
>> Repeat the steps you performed above, then run this command right after
>> hitting the breakpoint, and tell us what it prints:
>>
>>   print options & ~0x07ff
>>
> 

-- 
Brad Mells
Quantum Harmonics
889 Mowry Ave #86
Fremont CA 94536

619.808.2359





Information forwarded to owner <at> debbugs.gnu.org, bug-coreutils <at> gnu.org:
bug#6500; Package coreutils. (Fri, 25 Jun 2010 05:18:01 GMT) Full text and rfc822 format available.

Message #26 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Jim Meyering <jim <at> meyering.net>
To: Brad <b.mells <at> outwild.net>
Cc: 6500-done <at> debbugs.gnu.org, bug-coreutils <at> gnu.org
Subject: Re: rm 8.1
Date: Fri, 25 Jun 2010 07:17:15 +0200
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.




Reply sent to Jim Meyering <jim <at> meyering.net>:
You have taken responsibility. (Fri, 25 Jun 2010 05:18:02 GMT) Full text and rfc822 format available.

Notification sent to Jim Meyering <jim <at> meyering.net>:
bug acknowledged by developer. (Fri, 25 Jun 2010 05:18:02 GMT) Full text and rfc822 format available.

bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Fri, 23 Jul 2010 11:24:03 GMT) Full text and rfc822 format available.

This bug report was last modified 14 years and 330 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.