The current regex code may call mch_breakcheck which can process X events.
One of these events could be a remote_expr that makes its own call into the
regex engine. This usually crashes because the regex engine isn't
reentrant. This is probably also a problem for anything else that runs long
enough to make breakchecks and isn't reentrant.

This crash can usually be reproduced in linux by running vim with a
--servername argument and typing the command:
:call system("sleep 1 && vim --servername ".v:servername." --remote-expr
'substitute(string(range(5000)), \"a\", \"b\", \"g\")' &") | call
substitute(string(range(5000)), '\(,.*\)\@<!,', '', 'g')

The attached patch fixes the problem by preventing RealWaitForChar from
processing X events if it is called from mch_breakcheck.

Thanks,
James

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
diff --git a/src/os_unix.c b/src/os_unix.c
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -177,9 +177,9 @@
 
 static int  WaitForChar __ARGS((long));
 #if defined(__BEOS__) || defined(VMS)
-int  RealWaitForChar __ARGS((int, long, int *));
+int  RealWaitForChar __ARGS((int, long, int *, int));
 #else
-static int  RealWaitForChar __ARGS((int, long, int *));
+static int  RealWaitForChar __ARGS((int, long, int *, int));
 #endif
 
 #ifdef FEAT_XCLIPBOARD
@@ -368,7 +368,7 @@
 {
     ignored = (int)write(1, (char *)s, len);
     if (p_wd)          /* Unix is too fast, slow down a bit more */
-       RealWaitForChar(read_cmd_fd, p_wd, NULL);
+       RealWaitForChar(read_cmd_fd, p_wd, NULL, 1);
 }
 
 /*
@@ -4833,7 +4833,7 @@
                     * to some terminal (vt52?).
                     */
                    ++noread_cnt;
-                   while (RealWaitForChar(fromshell_fd, 10L, NULL))
+                   while (RealWaitForChar(fromshell_fd, 10L, NULL, 1))
                    {
                        len = read_eintr(fromshell_fd, buffer
 # ifdef FEAT_MBYTE
@@ -5114,7 +5114,7 @@
     void
 mch_breakcheck()
 {
-    if (curr_tmode == TMODE_RAW && RealWaitForChar(read_cmd_fd, 0L, NULL))
+    if (curr_tmode == TMODE_RAW && RealWaitForChar(read_cmd_fd, 0L, NULL, 0))
        fill_input_buf(FALSE);
 }
 
@@ -5171,9 +5171,9 @@
 # endif
 # ifdef FEAT_MOUSE_GPM
        gpm_process_wanted = 0;
-       avail = RealWaitForChar(read_cmd_fd, msec, &gpm_process_wanted);
+       avail = RealWaitForChar(read_cmd_fd, msec, &gpm_process_wanted, 1);
 # else
-       avail = RealWaitForChar(read_cmd_fd, msec, NULL);
+       avail = RealWaitForChar(read_cmd_fd, msec, NULL, 1);
 # endif
        if (!avail)
        {
@@ -5195,7 +5195,7 @@
          );
 
 #else
-    avail = RealWaitForChar(read_cmd_fd, msec, NULL);
+    avail = RealWaitForChar(read_cmd_fd, msec, NULL, 1);
 #endif
     return avail;
 }
@@ -5214,10 +5214,11 @@
 #else
     static  int
 #endif
-RealWaitForChar(fd, msec, check_for_gpm)
+RealWaitForChar(fd, msec, check_for_gpm, allow_x)
     int                fd;
     long       msec;
     int                *check_for_gpm UNUSED;
+    int                allow_x UNUSED; /* If 0, it is dangerous to handle X 
events */
 {
     int                ret;
 #ifdef FEAT_NETBEANS_INTG
@@ -5310,13 +5311,16 @@
        }
 # endif
 # ifdef FEAT_XCLIPBOARD
-       may_restore_clipboard();
-       if (xterm_Shell != (Widget)0)
+       if (allow_x)
        {
-           xterm_idx = nfd;
-           fds[nfd].fd = ConnectionNumber(xterm_dpy);
-           fds[nfd].events = POLLIN;
-           nfd++;
+           may_restore_clipboard();
+           if (xterm_Shell != (Widget)0)
+           {
+               xterm_idx = nfd;
+               fds[nfd].fd = ConnectionNumber(xterm_dpy);
+               fds[nfd].events = POLLIN;
+               nfd++;
+           }
        }
 # endif
 # ifdef FEAT_MOUSE_GPM
@@ -5366,12 +5370,15 @@
        }
 # endif
 # ifdef FEAT_XCLIPBOARD
-       if (xterm_Shell != (Widget)0 && (fds[xterm_idx].revents & POLLIN))
+       if (allow_x)
        {
-           xterm_update();      /* Maybe we should hand out clipboard */
-           if (--ret == 0 && !input_available())
-               /* Try again */
-               finished = FALSE;
+           if (xterm_Shell != (Widget)0 && (fds[xterm_idx].revents & POLLIN))
+           {
+               xterm_update();      /* Maybe we should hand out clipboard */
+               if (--ret == 0 && !input_available())
+                   /* Try again */
+                   finished = FALSE;
+           }
        }
 # endif
 # ifdef FEAT_MOUSE_GPM
@@ -5463,16 +5470,19 @@
        }
 # endif
 # ifdef FEAT_XCLIPBOARD
-       may_restore_clipboard();
-       if (xterm_Shell != (Widget)0)
+       if (allow_x)
        {
-           FD_SET(ConnectionNumber(xterm_dpy), &rfds);
-           if (maxfd < ConnectionNumber(xterm_dpy))
-               maxfd = ConnectionNumber(xterm_dpy);
-
-           /* An event may have already been read but not handled.  In
-            * particulary, XFlush may cause this. */
-           xterm_update();
+           may_restore_clipboard();
+           if (xterm_Shell != (Widget)0)
+           {
+               FD_SET(ConnectionNumber(xterm_dpy), &rfds);
+               if (maxfd < ConnectionNumber(xterm_dpy))
+                   maxfd = ConnectionNumber(xterm_dpy);
+
+               /* An event may have already been read but not handled.  In
+                * particulary, XFlush may cause this. */
+               xterm_update();
+           }
        }
 # endif
 # ifdef FEAT_MOUSE_GPM
@@ -5544,16 +5554,19 @@
        }
 # endif
 # ifdef FEAT_XCLIPBOARD
-       if (ret > 0 && xterm_Shell != (Widget)0
-               && FD_ISSET(ConnectionNumber(xterm_dpy), &rfds))
+       if (allow_x)
        {
-           xterm_update();           /* Maybe we should hand out clipboard */
-           /* continue looping when we only got the X event and the input
-            * buffer is empty */
-           if (--ret == 0 && !input_available())
+           if (ret > 0 && xterm_Shell != (Widget)0
+                   && FD_ISSET(ConnectionNumber(xterm_dpy), &rfds))
            {
-               /* Try again */
-               finished = FALSE;
+               xterm_update();       /* Maybe we should hand out clipboard */
+               /* continue looping when we only got the X event and the input
+                * buffer is empty */
+               if (--ret == 0 && !input_available())
+               {
+                   /* Try again */
+                   finished = FALSE;
+               }
            }
        }
 # endif
diff --git a/src/proto/os_vms.pro b/src/proto/os_vms.pro
--- a/src/proto/os_vms.pro
+++ b/src/proto/os_vms.pro
@@ -12,5 +12,5 @@
 int mch_expandpath __ARGS((garray_T *gap, char_u *path, int flags));
 void *vms_fixfilename __ARGS((void *instring));
 void vms_remove_version __ARGS((void *fname));
-int RealWaitForChar __ARGS((int fd, long msec, int *check_for_gpm));
+int RealWaitForChar __ARGS((int fd, long msec, int *check_for_gpm, int 
allow_x));
 /* vim: set ft=c : */
diff --git a/src/ui.c b/src/ui.c
--- a/src/ui.c
+++ b/src/ui.c
@@ -1801,7 +1801,7 @@
      * On the BeBox version (for now), all input is secretly performed within
      * beos_select() which is called from RealWaitForChar().
      */
-    while (!vim_is_input_buf_full() && RealWaitForChar(read_cmd_fd, 0, NULL))
+    while (!vim_is_input_buf_full() && RealWaitForChar(read_cmd_fd, 0, NULL, 
1))
            ;
     len = inbufcount;
     inbufcount = 0;

Raspunde prin e-mail lui