From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Chong Yidong Newsgroups: gmane.emacs.devel Subject: Re: SEGV in x_catch_errors_unwind (x86_64-unknown-linux-gnu) Date: Sat, 25 Feb 2006 10:36:01 -0500 Message-ID: <87vev3v4bi.fsf@stupidchicken.com> References: <17403.34595.452779.27043@segfault.lan> <17408.2816.556166.916490@segfault.lan> <87zmkfv51z.fsf@stupidchicken.com> NNTP-Posting-Host: main.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: sea.gmane.org 1140881917 10857 80.91.229.2 (25 Feb 2006 15:38:37 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Sat, 25 Feb 2006 15:38:37 +0000 (UTC) Cc: rms@gnu.org, emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sat Feb 25 16:38:36 2006 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by ciao.gmane.org with esmtp (Exim 4.43) id 1FD1V7-00083A-NQ for ged-emacs-devel@m.gmane.org; Sat, 25 Feb 2006 16:38:30 +0100 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1FD1V8-0004pL-H6 for ged-emacs-devel@m.gmane.org; Sat, 25 Feb 2006 10:38:30 -0500 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1FD1Sq-0007xS-9m for emacs-devel@gnu.org; Sat, 25 Feb 2006 10:36:08 -0500 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1FD1So-0007sr-2c for emacs-devel@gnu.org; Sat, 25 Feb 2006 10:36:06 -0500 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1FD1Sm-0007pG-HG for emacs-devel@gnu.org; Sat, 25 Feb 2006 10:36:05 -0500 Original-Received: from [18.95.6.7] (helo=outgoing.mit.edu) by monty-python.gnu.org with esmtp (Exim 4.52) id 1FD1T3-0001fS-Hz; Sat, 25 Feb 2006 10:36:21 -0500 Original-Received: by outgoing.mit.edu (Postfix, from userid 1000) id 5FAA21E40A9; Sat, 25 Feb 2006 10:36:01 -0500 (EST) Original-To: "John W. Eaton" In-Reply-To: <87zmkfv51z.fsf@stupidchicken.com> (Chong Yidong's message of "Sat, 25 Feb 2006 10:20:08 -0500") User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (gnu/linux) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:50964 Archived-At: Chong Yidong writes: >> However, as I was looking at the following loop unbind_to in eval.c, >> it occurred to me that one way the x_catch_errors_unwind function >> could be called twice in succession would be if specpdl_ptr is >> incremented by the addition of additional bindings while the loop is >> running (by some other code that is misbehaving while manipulating the >> specpdl array). There isn't any misbehaving code, btw. Since unbind_to is currently run without BLOCK_INPUT, it can be interrupted by a signal handler. The signal handler can call the x error handler, which calls record_unwind_protect, which screws things up. One solution is to somehow re-engineer the x error handler not to use record_unwind_protect. The other is to block inputs at the point in unbind_to where specpdl_ptr is being modified, like this: *** emacs/src/eval.c.~1.261.~ 2006-02-09 23:33:56.000000000 -0500 --- emacs/src/eval.c 2006-02-25 10:26:26.000000000 -0500 *************** *** 3214,3233 **** { Lisp_Object quitf = Vquit_flag; struct gcpro gcpro1, gcpro2; GCPRO2 (value, quitf); Vquit_flag = Qnil; ! while (specpdl_ptr != specpdl + count) { /* Copy the binding, and decrement specpdl_ptr, before we do the work to unbind it. We decrement first so that an error in unbinding won't try to unbind the same entry again, and we copy the binding first in case more bindings are made during some of the code we run. */ - struct specbinding this_binding; this_binding = *--specpdl_ptr; if (this_binding.func != 0) (*this_binding.func) (this_binding.old_value); --- 3214,3238 ---- { Lisp_Object quitf = Vquit_flag; struct gcpro gcpro1, gcpro2; + struct specbinding this_binding; GCPRO2 (value, quitf); Vquit_flag = Qnil; ! while (1) { + BLOCK_INPUT; + if (specpdl_ptr == specpdl + count) + break; + /* Copy the binding, and decrement specpdl_ptr, before we do the work to unbind it. We decrement first so that an error in unbinding won't try to unbind the same entry again, and we copy the binding first in case more bindings are made during some of the code we run. */ this_binding = *--specpdl_ptr; + UNBLOCK_INPUT; if (this_binding.func != 0) (*this_binding.func) (this_binding.old_value); *************** *** 3263,3268 **** --- 3268,3274 ---- set_internal (this_binding.symbol, this_binding.old_value, 0, 1); } } + UNBLOCK_INPUT; if (NILP (Vquit_flag) && !NILP (quitf)) Vquit_flag = quitf;