Dominique Pelle wrote:
> On Feb 11, 2008 10:28 PM, Bram Moolenaar <[EMAIL PROTECTED]> wrote:
> >
> > Dominique Pelle wrote:
> >
> > > On Feb 5, 2008 8:40 AM, Tony Mechelynck <[EMAIL PROTECTED]> wrote:
> > > >
> > > > Kazuo Teramoto wrote:
> > > > >> Same (start at X, stop at Y) for
> > > > >> :call search("^", "e")
> > > > >> :call search("^", "ce")
> > > > >
> > > > > Ouch, for me this is a little more serious, if I try this calls my vim
> > > > > always segfault (I don't need a test file and using -u NONE -U none),
> > > > > I don't know what need to be posted but the :version is
> > > > >
> > > > > VIM - Vi IMproved 7.0 (2006 May 7, compiled Aug 29 2007 10:59:43)
> > > > > Included patches: 1-122, 234-235, 39
> > > > > Big version without GUI. Features included (+) or not (-):
> > > >
> > > > ??? with patch 39 applied twice ??? none of 123-233 (a hundred and
> > > > eleven
> > > > missing patches) ??? and no "compiled-by" line ??? Oh, and it's a 7.0
> > > > anyway.
> > > > Maybe you ought to install a 7.1 version (of which the current
> > > > patchlevel is
> > > > 7.1.242)? See my "HowTo" page,
> > > > http://users.skynet.be/antoine.mechelynck/vim/compunix.htm
> > >
> > >
> > > I have a normal installation of vim-7.1.242 (all patches) and it's
> > > crashing for me as well. I have the same version of vim on
> > > 2 machines (one linux x66 and one linux x86_64) and it's only
> > > crashing on the the x86_64 machine only.
> > >
> > > As soon as I type ":call search('\_s*a\_s*','e')" I get a core dump
> > > on the x86_64 machine:
> > >
> > > $ ./vim
> > > Vim: Caught deadly signal SEGV
> > > Vim: preserving files...
> > > Vim: Finished.
> > > Segmentation fault (core dumped)
> > >
> > > $ gdb ./vim core
> > > ...
> > > Core was generated by `./vim'.
> > > Program terminated with signal 11, Segmentation fault.
> > > #0 0x00002b71866ebe47 in kill () from /lib64/libc.so.6
> > > (gdb) bt
> > > #0 0x00002b71866ebe47 in kill () from /lib64/libc.so.6
> > > #1 0x000000000050e38d in may_core_dump () at os_unix.c:2950
> > > #2 0x000000000050e328 in mch_exit (r=1) at os_unix.c:2915
> > > #3 0x00000000004a5eb3 in getout (exitval=1) at main.c:1342
> > > #4 0x00000000004d2128 in preserve_exit () at misc1.c:8355
> > > #5 0x000000000050c73d in deathtrap (sigarg=11) at os_unix.c:1030
> > > #6 <signal handler called>
> > > #7 0x00000000004e0b33 in utf_head_off (base=0x9251c4 "c Y",
> > > p=0x1009251c3 <Address 0x1009251c3 out of bounds>) at mbyte.c:2480
> > > #8 0x0000000000539235 in searchit (win=0x831b90, buf=0x8333f0,
> > > pos=0x7fff2690fa00, dir=1, pat=0x947c80 "\\_s*a\\_s*", count=1,
> > > options=1088, pat_use=0, stop_lnum=0, tm=0x7fff2690f9e0) at
> > > search.c:848
> > > #9 0x00000000004420e7 in search_cmn (argvars=0x7fff2690fbc0,
> > > match_pos=0x0,
> > > flagsp=0x7fff2690fa8c) at eval.c:14077
> > > #10 0x00000000004421cc in f_search (argvars=0x7fff2690fbc0,
> > > rettv=0x7fff2690fd80) at eval.c:14120
> > > #11 0x0000000000439522 in call_func (name=0x986920 "search", len=6,
> > > rettv=0x7fff2690fd80, argcount=2, argvars=0x7fff2690fbc0, firstline=1,
> > > lastline=1, doesrange=0x7fff2690fd7c, evaluate=1, selfdict=0x0)
> > > at eval.c:7632
> > > #12 0x0000000000439043 in get_func_tv (name=0x986920 "search", len=6,
> > > rettv=0x7fff2690fd80, arg=0x7fff2690fda0, firstline=1, lastline=1,
> > > doesrange=0x7fff2690fd7c, evaluate=1, selfdict=0x0) at eval.c:7450
> > > #13 0x0000000000432c73 in ex_call (eap=0x7fff2690fe80) at eval.c:3215
> > > #14 0x0000000000463c6b in do_one_cmd (cmdlinep=0x7fff26910528, sourcing=0,
> > > cstack=0x7fff26910080, fgetline=0x47821a <getexline>, cookie=0x0)
> > > at ex_docmd.c:2623
> > > #15 0x000000000046146a in do_cmdline (cmdline=0x0,
> > > getline=0x47821a <getexline>, cookie=0x0, flags=0) at ex_docmd.c:1099
> > > #16 0x00000000004ebdd2 in nv_colon (cap=0x7fff26910670) at normal.c:5179
> > > #17 0x00000000004e4dd8 in normal_cmd (oap=0x7fff26910730, toplevel=1)
> > > at normal.c:1152
> > > #18 0x00000000004a5be2 in main_loop (cmdwin=0, noexmode=0) at main.c:1181
> > > #19 0x00000000004a572e in main (argc=1, argv=0x7fff26910a28) at main.c:940
> > >
> > > (gdb) up
> > > #1 0x000000000050e38d in may_core_dump () at os_unix.c:2950
> > > 2950 kill(getpid(), deadly_signal); /* Die using the
> > > signal we caught */
> > > (gdb)
> > > #2 0x000000000050e328 in mch_exit (r=1) at os_unix.c:2915
> > > 2915 may_core_dump();
> > > (gdb)
> > > #3 0x00000000004a5eb3 in getout (exitval=1) at main.c:1342
> > > 1342 mch_exit(exitval);
> > > (gdb)
> > > #4 0x00000000004d2128 in preserve_exit () at misc1.c:8355
> > > 8355 getout(1);
> > > (gdb)
> > > #5 0x000000000050c73d in deathtrap (sigarg=11) at os_unix.c:1030
> > > 1030 preserve_exit(); /* preserve files and exit */
> > > (gdb)
> > > #6 <signal handler called>
> > > (gdb)
> > > #7 0x00000000004e0b33 in utf_head_off (base=0x9251c4 "c Y",
> > > p=0x1009251c3 <Address 0x1009251c3 out of bounds>) at mbyte.c:2480
> > > 2480 if (*p < 0x80) /* be quick for ASCII */
> > > (gdb) p p
> > > $1 = (char_u *) 0x1009251c3 <Address 0x1009251c3 out of bounds>
> > >
> > > -> pointer 'p' is invalid
> > >
> > > Valgrind memory checker also detects a problem when
> > > doing ":call search('\_s*a\_s*','e')" at the same location
> > > on the x86_64 machine (no problem detected on the
> > > x86 machine):
> > >
> > > ==13671== Invalid read of size 1
> > > ==13671== at 0x4E0B33: utf_head_off (mbyte.c:2480)
> > > ==13671== by 0x539234: searchit (search.c:848)
> > > ==13671== by 0x4420E6: search_cmn (eval.c:14077)
> > > ==13671== by 0x4421CB: f_search (eval.c:14120)
> > > ==13671== by 0x439521: call_func (eval.c:7632)
> > > ==13671== by 0x439042: get_func_tv (eval.c:7450)
> > > ==13671== by 0x432C72: ex_call (eval.c:3215)
> > > ==13671== by 0x463C6A: do_one_cmd (ex_docmd.c:2623)
> > > ==13671== by 0x461469: do_cmdline (ex_docmd.c:1099)
> > > ==13671== by 0x4EBDD1: nv_colon (normal.c:5179)
> > > ==13671== by 0x4E4DD7: normal_cmd (normal.c:1152)
> > > ==13671== by 0x4A5BE1: main_loop (main.c:1181)
> > > ==13671== by 0x4A572D: main (main.c:940)
> > > ==13671== Address 0x10b5e697f is not stack'd, malloc'd or (recently)
> > > free'd
> > >
> > > I can reproduce it 100% of the time.
> >
> > What is the text you are searching in? I assume your 'encoding' is set
> > to "utf-8"?
>
>
> I'm doing the exact same thing as described in the first email
> of this thread, i.e. the buffer contains only 2 lines, the cursor
> is on first character X:
>
> X a
> c Y
>
> Then I call...
>
> :call search('\_s*a\_s*','e')
>
> ... and it crashes as described on one machine (x86_64).
> On the other machine (x86), it does not crash but cursor
> moves to Y (which is not right either from initial bug submitter).
>
> Encoding is utf-8 on both machines.
>
> I've updated to latest vim-7.1.245 on both hosts with
> same results (one works, the other one crashes).
>
>
> > If you want to do a little digging, check out the code before calling
> > mb_head_off(), line 848 in search.c. Especially the value of "endpos"
> > compared to what's in the text.
>
> I've put the following debug fprintf(stderr, ...) on line 848 before
> call to (*mb_head_off)(...) (without changing line numbers in original
> code):
>
> fprintf(stderr, "%s:%d options=0x%x lnum=%ld endpos.lnum=%ld
> endpos.col=%d pos->lnum=%ld pos->col=%d buf=%p
> buf->b_ml.ml_line_count=%ld ptr=%p *ptr=%d\n", __FILE__, __LINE__,
> options, lnum, endpos.lnum, endpos.col, pos->lnum, pos->col, buf,
> buf->b_ml.ml_line_count, ptr, *ptr);
>
> ... and the following fprintf(stderr, ...) in mbyte.c before
> dereferencing p pointer at line mbyte.c:2480:
>
> fprintf(stderr, "%s:%d p=%p\n", __FILE__, __LINE__, p);
>
>
> On host where it does not crash I see:
>
> search.c:848 options=0x440 lnum=1 endpos.lnum=1 endpos.col=0
> pos->lnum=2 pos->col=-1 buf=0x81f3110 buf->b_ml.ml_line_count=2
> ptr=0x82feca8 *ptr=99
>
> mbyte.c:2479 p=0x82feca7
>
>
> On host where it crashes, I see:
>
> search.c:848 options=0x440 lnum=1 endpos.lnum=1 endpos.col=0
> pos->lnum=2 pos->col=-1 buf=0x8333f0 buf->b_ml.ml_line_count=2
> ptr=0x919a88 *ptr=99
>
> mbyte.c:2479 p=0x100919a87
>
>
> Ahh! I get it. Notice that pos->col is -1. When doing the pointer
> arithmetics at line search.c:848 (ptr + pos->col) something goes terribly
> wrong:
>
> 0x82feca8 + (-1) -> p=0x82feca7 ... and no crash (that's on the 32 bits
> Linux)
> 0x919a88 + (-1) -> 0x100919a87 ... and crash (that's on the 64 bits Linux)
>
> It actually adds 4294967295 to the pointer, instead of removing -1.
>
> type pos pos is:
>
> typedef struct
> {
> linenr_T lnum; /* line number */
> colnr_T col; /* column number */
> } lpos_T;
>
> and type of colnr_T is
>
> typedef unsigned colnr_T;
>
>
> Notice that it's unsigned. So that explains why it adds a large value to the
> pointer instead of -1. On the 32 bits host, it works because pointer
> wraps around 32 bits. On the 64 bits, pointer does not wrap on 32 bits
> hence crash.
>
> I can fix the crash by adding a cast as follows, but I think it's probably
> wrong to have column 0 and remove 1 to it in the first place. This cast
> is only masking the root cause of the problems:
>
> diff -c -r1.64 search.c
> *** search.c 26 Jan 2008 20:15:46 -0000 1.64
> --- search.c 12 Feb 2008 09:13:21 -0000
> ***************
> *** 845,851 ****
> ptr = (char_u *)"";
> else
> ptr = ml_get_buf(buf, pos->lnum, FALSE);
> ! pos->col -= (*mb_head_off)(ptr, ptr + pos->col);
> }
> #endif
> }
> --- 845,851 ----
> ptr = (char_u *)"";
> else
> ptr = ml_get_buf(buf, pos->lnum, FALSE);
> ! pos->col -= (*mb_head_off)(ptr, ptr +
> (int)pos->col);
> }
> #endif
> }
>
>
> -- Dominique
Thanks for figuring this out. We probably need to avoid that pos->col
is decremented below zero. I'll look into it.
> I should add that the endpos value was set at line search.c:623
> After line search.c:623, we have:
>
> matchpos=0,1 (line 0, col 1)
> endpos=1,0 (line 1, col 0).
>
> I don't think it's right to have col=0, is it?
>
> If so, that would mean it's a bug in vim_regexec_multi(...).
It's probably OK for the end position to be in column zero. It means
the match ends before the first column. Looks like this isn't handled
properly, since "col - 1" will be negative.
--
hundred-and-one symptoms of being an internet addict:
26. You check your mail. It says "no new messages." So you check it again.
/// Bram Moolenaar -- [EMAIL PROTECTED] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ download, build and distribute -- http://www.A-A-P.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---