On 9/14/06, Bram Moolenaar <[EMAIL PROTECTED]> wrote:

Yakov Lerner wrote:

> On 9/14/06, Haakon Riiser <[EMAIL PROTECTED]> wrote:
> > After recompiling Vim with -D_FILE_OFFSET_BITS=64, everything
> > involving tags break, including the help system.  Typing :h,
> > or pressing ^] to jump to a tag, causes Vim to get caught in an
> > infinite loop.
> >
> > Is there another way to get large file support that works?
> > There's no ./configure argument to enable it, so I just added
> > the above macro definition flag in CFLAGS.  The problem with
> > not having large file support is not that I need to edit files
> > larger than 2 GiB, but that ^X^F doesn't expand large files,
> > probably because stat() fails with EOVERFLOW.
> >
> > By the way, this problem was encountered on the following system:
> >
> > OS: Slackware Linux 10.2
> > Libc: 2.3.5
> > GCC: several versions: 3.3.6, 3.4.6, 4.1.1
> > Vim: several versions, including 7.0.0 and 7.0.101
>
> I also get infinite loop when I build vim with -D_FILE_OFFSET_BITS=64
> on FedoraCode 3.
>
> Applying 'strace -p' shows that vim is stuck searching for
> tag, see the trace below. Apparently some read() in vim
> does not have check for == 0 return value.
>
> Yakov
>
> [ here vim searches for tags in other file ... then ...]
> open("/home/lerner/.vim/doc/tags", O_RDONLY|O_LARGEFILE) = 3
> fstat64(3, {st_mode=S_IFREG|0644, st_size=2506, ...}) = 0
> mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1,
> 0) = 0xb7fbf000
> read(3, ":Brightness\txterm16.txt\t/*:Brigh"..., 4096) = 2506
> _llseek(3, 0, [2506], SEEK_END)         = 0
> _llseek(3, 0, [0], SEEK_SET)            = 0
> _llseek(3, 0, [0], SEEK_SET)            = 0
> read(3, ":Brightness\txterm16.txt\t/*:Brigh"..., 4096) = 2506
> read(3, "", 4096)                       = 0
> read(3, "", 4096)                       = 0
> read(3, "", 4096)                       = 0
> read(3, "", 4096)                       = 0
> read(3, "", 4096)                       = 0
> read(3, "", 4096)                       = 0
> .... infinite .........

Can you find out where in the code this happens?

I suspect the 64 bit library functions work different from the "normal"
functions.  Perhaps fgets(), since that's what is being used to read the
tags file.

In situation where fgets() returns NULL, find_tags() enters
infinite loop as follows.

(gdb) where
#0  0xffffe410 in ?? ()
#1  0xbff7bab0 in ?? ()
#2  0x00000015 in ?? ()
#3  0xb7f7b000 in ?? ()
#4  0x00235573 in __write_nocancel () from /lib/tls/libc.so.6
#5  0x001dc57f in _IO_new_file_write () from /lib/tls/libc.so.6
#6  0x001db02b in _IO_new_do_write () from /lib/tls/libc.so.6
#7  0x001dba70 in _IO_new_file_overflow () from /lib/tls/libc.so.6
#8  0x001dd1ca in __overflow () from /lib/tls/libc.so.6
#9  0x001d351f in puts () from /lib/tls/libc.so.6
#10 0x080c2bcc in vim_fgets (
   buf=0x8244a78
"xterm16fg_GroupName\txterm16.txt\t/*xterm16fg_GroupName*\n",
size=512,
   fp=0x827c1f8) at fileio.c:5853
#11 0x08177494 in find_tags (pat=0x8244568 "[EMAIL PROTECTED]",
num_matches=0x14, matchesp=0x14, flags=40,
   mincount=1, buf_ffname=0x0) at tag.c:1625
#12 0x08178b35 in do_tag (tag=0x81f1168 "[EMAIL PROTECTED]", type=1, count=1,
forceit=0, verbose=1)
   at tag.c:548
#13 0x080a3b08 in ex_help (eap=0x827d1b0) at ex_cmds.c:5519
#14 0x080b1e72 in do_one_cmd (cmdlinep=0xbff7ce08, sourcing=0,
cstack=0xbff7ce80,
   fgetline=0x80c1828 <getexline>, cookie=0x0) at ex_docmd.c:2616
#15 0x080b3082 in do_cmdline (cmdline=0x0, getline=0x80c1828
<getexline>, cookie=0x0, flags=0)
   at ex_docmd.c:1098
#16 0x08113620 in nv_colon (cap=0xbff7d220) at normal.c:5150
#17 0x08116d2f in normal_cmd (oap=0xbff7d290, toplevel=1) at normal.c:1137
#18 0x080decee in main_loop (cmdwin=0, noexmode=0) at main.c:1154
#19 0x080e2077 in main (argc=20, argv=0x14) at main.c:934
(gdb) b tag.c:1626
Breakpoint 1 at 0x8177494: file tag.c, line 1626.
(gdb) cont
Continuing.

Breakpoint 1, find_tags (pat=0x8244568 "[EMAIL PROTECTED]", num_matches=0x1,
matchesp=0x1, flags=40,
   mincount=1, buf_ffname=0x0) at tag.c:1626
1626                    if (!eof && search_info.curr_offset != 0)
(gdb) n
1625                    eof = tag_fgets(lbuf, LSIZE, fp);
(gdb) n
1626                    if (!eof && search_info.curr_offset != 0)
(gdb) n
1651                        search_info.match_offset = ftell(fp);
(gdb) n
1650                        state = TS_SKIP_BACK;
(gdb) n
1651                        search_info.match_offset = ftell(fp);
(gdb) n
1652                        search_info.curr_offset =
search_info.curr_offset_used;
(gdb) n
1860                    continue;
(gdb) n
1652                        search_info.curr_offset =
search_info.curr_offset_used;
(gdb) n
1562                line_breakcheck();      /* check for CTRL-C typed */
(gdb) n
1564                if ((flags & TAG_INS_COMP)) /* Double brackets for gcc */
(gdb) n
1566                if (got_int || compl_interrupted)
(gdb) n
1576                if (mincount == TAG_MANY && match_count >= TAG_MANY)
(gdb) n
1582                if (get_it_again)
(gdb) n
1588                if (state == TS_BINARY)
(gdb) n
1601                else if (state == TS_SKIP_BACK)
(gdb) n
1603                    search_info.curr_offset -= LSIZE * 2;
(gdb) n
1604                    if (search_info.curr_offset < 0)
(gdb) n
1616                if (state == TS_BINARY || state == TS_SKIP_BACK)
(gdb) n
1621                    fseeko(fp, search_info.curr_offset, SEEK_SET);
(gdb) n
1619                    search_info.curr_offset_used = search_info.curr_offset;
(gdb) n
1621                    fseeko(fp, search_info.curr_offset, SEEK_SET);
(gdb) n
1619                    search_info.curr_offset_used = search_info.curr_offset;
(gdb) n
1621                    fseeko(fp, search_info.curr_offset, SEEK_SET);
(gdb) n
1619                    search_info.curr_offset_used = search_info.curr_offset;
(gdb) n
1621                    fseeko(fp, search_info.curr_offset, SEEK_SET);
(gdb) n
1625                    eof = tag_fgets(lbuf, LSIZE, fp);
(gdb) n

Breakpoint 1, find_tags (pat=0x8244568 "[EMAIL PROTECTED]", num_matches=0x1,
matchesp=0x1, flags=40,
   mincount=1, buf_ffname=0x0) at tag.c:1626
1626                    if (!eof && search_info.curr_offset != 0)
(gdb) n
1625                    eof = tag_fgets(lbuf, LSIZE, fp);
(gdb)
1626                    if (!eof && search_info.curr_offset != 0)
(gdb) p eof
$1 = 1
(gdb)

My line numbers in tag.c are as follows:

1625                 eof = tag_fgets(lbuf, LSIZE, fp);
1626                 if (!eof && search_info.curr_offset != 0)
1627                 {
1628                     search_info.curr_offset = ftell(fp);
1629                     if (search_info.curr_offset == search_info.high_offset)
1630                     {
1631                         /* oops, gone a bit too far; try from low offset */
1632 #ifdef HAVE_FSEEKO
1633                         fseeko(fp, search_info.low_offset, SEEK_SET);
1634 #else
1635                         fseek(fp, (long)search_info.low_offset, SEEK_SET);
1636 #endif
1637                         search_info.curr_offset = search_info.low_offset;
1638                     }
1639                     eof = tag_fgets(lbuf, LSIZE, fp);
1640                 }
1641                 /* skip empty and blank lines */
1642                 while (!eof && vim_isblankline(lbuf))
1643                 {
1644                     search_info.curr_offset = ftell(fp);
1645                     eof = tag_fgets(lbuf, LSIZE, fp);
1646                 }
1647                 if (eof)
1648                 {
1649                     /* Hit end of file.  Skip backwards. */
1650                     state = TS_SKIP_BACK;
1651                     search_info.match_offset = ftell(fp);
1652                     search_info.curr_offset = search_info.curr_offset_used;
1653                     continue;
1654                 }
1655             }
1656
1657             /*
1658              * Not jumping around in the file: Read the next line.
1659              */
1660             else
1661 #endif
1662             {
1663                 /* skip empty and blank lines */
1664                 do
1665                 {
1666 #ifdef FEAT_CSCOPE
1667                     if (use_cscope)
1668                         eof = cs_fgets(lbuf, LSIZE);
1669                     else
1670 #endif
1671                         eof = tag_fgets(lbuf, LSIZE, fp);
1672                 } while (!eof && vim_isblankline(lbuf));
1673
1674                 if (eof)

Reply via email to