ag 2 <(echo 2) gets assertion "p >= path" failed: .. /cygwin-3.1.7 ... /cygwin/path.cc", line 3065, function: int symlink_info::check

Ken Brown kbrown@cornell.edu
Mon Sep 7 20:35:17 GMT 2020


On 9/6/2020 4:28 PM, Ken Brown via Cygwin wrote:
> On 9/6/2020 3:47 PM, Ken Brown via Cygwin wrote:
>> On 9/6/2020 2:43 PM, David Dyck via Cygwin wrote:
>>> This command triggers an assertion failure
>>>    "ag" is from the_silver_searcher
>>>
>>> $ ag 2 <(echo 2)
>>> assertion "p >= path" failed: file
>>> "/home/corinna/src/cygwin/cygwin-3.1.7/cygwin-3.1.7-1.x86_64/src/newlib-cygwin/winsup/cygwin/path.cc", 
>>>
>>> line 3065, function: int symlink_info::check(char*, const
>>> suffix_info*, fs_info&, path_conv_handle&)
>>> Aborted (core dumped)
>>>
>>>   3473k 2020/08/22 C:\cygwin64\bin\cygwin1.dll
>>>      Cygwin DLL version info:
>>>          DLL version: 3.1.7
>>> bash                                    4.4.12-3                        OK
>>> the_silver_searcher                     2.2.0-1                         OK
>> [...]
>>> assertion "p >= path" failed: file
>>> "/home/corinna/src/cygwin/cygwin-3.1.7/cygwin-3.1.7-1.x86_64/src/newlib-cygwin/winsup/cygwin/path.cc", 
>>>
>>> line 3065, function: int symlink_info::check(char*, const
>>> suffix_info*, fs_info&, path_conv_handle&)
>>> Aborted (core dumped)
>> [...]
>>> I've reported this on github as an "ag" bug, but I think it is a bug in cygwin
>>
>> An assertion failure in Cygwin code is a Cygwin bug.  I'll take a look.
> 
> Running
> 
>    bash -c '/usr/bin/ag 2 <(echo 2)'
> 
> under strace yields the following:
> 
>    242  191767 [main] ag 33659 open: open(/dev/fd/63/.ignore, 0x0)
> [...]
>     30  192584 [main] ag 33659 mount_info::conv_to_win32_path: src_path 
> /proc/self/fd/63/.ignore, dst /proc/self/fd/63/.ignore, flags 0x0, rc 0
> [...]
>     31  193366 [main] ag 33659 mount_info::conv_to_win32_path: 
> conv_to_win32_path (pipe:[4295036184]/.ignore)
> [...]
>     31  193550 [main] ag 33659 mount_info::conv_to_win32_path: 
> conv_to_win32_path (pipe:[4295036184])
> [...]
>     34  193615 [main] ag 33659 symlink_info::check: 0xC0000034 = NtCreateFile 
> (\??\C:pipe:[4295036184])
> 
> The assertion fails because the path 'C:pipe:[4295036184]' doesn't contain a 
> backslash.  But probably we should never have allowed ourselves to get to the 
> point of considering that path.

I've made some progress but haven't figured out the fix yet.  First, for easier 
debugging, here's a simpler way to reproduce the problem:

$ cat proc_bug.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>

int
main ()
{
   int fd[2];
   char fname[100];

   if (pipe (fd) < 0)
     {
       perror ("pipe");
       exit (1);
     }
   sprintf (fname, "/dev/fd/%d/foo", fd[0]);
   if (open (fname, O_RDONLY) < 0)
     {
       perror ("open");
       exit (1);
     }
}

$ gcc -o proc_bug proc_bug.c

$ ./proc_bug.exe
assertion "p >= path" failed: file 
"../../../../newlib-cygwin/winsup/cygwin/path.cc", line 3065, function: int 
symlink_info::check(char*, const suffix_info*, fs_info&, path_conv_handle&)
Aborted (core dumped)

Here's what happens.  The program is trying to open /dev/fd/3/foo, where file 
descriptor 3 is the read end of a pipe.  path_conv check resolves this to 
/proc/<pid>/fd/3/foo, creates an fhandler_process for this path, and calls (at 
path.cc:782) fhandler_process::exists.  The latter fills the filebuf with 
"pipe:[xxxxxxxxxx]/foo" and returns virt_fsdir.  We're now at path.cc:808, and 
everything is set up for the assertion failure.

I think fhandler_process::exists is not doing the right thing here, but I'm not 
familiar with this part of the code, so I'll have to stare at it for a while to 
see what's going wrong.

Corinna, if you are able to see it more quickly and want to go ahead and fix it, 
you won't hurt my feelings.

Ken


More information about the Cygwin mailing list