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;