From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Daniel Colascione Newsgroups: gmane.emacs.devel Subject: Re: [PATCH] Unconditional quit on SIGUSR2 Date: Mon, 28 Mar 2011 12:29:29 -0700 Message-ID: <4D90E199.2040809@gmail.com> References: <4D90354E.9000704@gmail.com> <4D908F5F.8000303@gmail.com> <4D90C42F.9060500@gmail.com> <83bp0vrszf.fsf@gnu.org> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Trace: dough.gmane.org 1301340596 5290 80.91.229.12 (28 Mar 2011 19:29:56 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Mon, 28 Mar 2011 19:29:56 +0000 (UTC) Cc: emacs-devel@gnu.org To: Eli Zaretskii Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon Mar 28 21:29:51 2011 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Q4I8K-0001C3-Fw for ged-emacs-devel@m.gmane.org; Mon, 28 Mar 2011 21:29:49 +0200 Original-Received: from localhost ([127.0.0.1]:46251 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Q4I8I-0001pc-Fx for ged-emacs-devel@m.gmane.org; Mon, 28 Mar 2011 15:29:46 -0400 Original-Received: from [140.186.70.92] (port=48925 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Q4I8A-0001of-KF for emacs-devel@gnu.org; Mon, 28 Mar 2011 15:29:41 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Q4I87-0006hP-L5 for emacs-devel@gnu.org; Mon, 28 Mar 2011 15:29:36 -0400 Original-Received: from mail-pz0-f41.google.com ([209.85.210.41]:45504) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Q4I86-0006h3-0m; Mon, 28 Mar 2011 15:29:34 -0400 Original-Received: by pzk32 with SMTP id 32so830347pzk.0 for ; Mon, 28 Mar 2011 12:29:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:message-id:date:from:user-agent:mime-version:to :cc:subject:references:in-reply-to:content-type :content-transfer-encoding; bh=aRc8R/ix8YTpvYXa3tp/CF1GENWQeH/Ra3yzRrliAGk=; b=xfS+BM2EV0DtJ8+00uz7+EFNugWu1Nb7fOSgkArd3fu6KJSItkgLTPgR3hJExp51oJ zz7TVI2Z+6B/NgAq+887Cq7HwRxM+WbaMe/UjufziGim8hcqJU2dX/n73aQNVwRebcXq QMT0ajUQfHbW4rY4ilcFsUJ3U0VInrgSU04wg= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:user-agent:mime-version:to:cc:subject :references:in-reply-to:content-type:content-transfer-encoding; b=V7T2MstXRuolVIUGErNQQNsykET1ZrvPtKplQjKaUpTtbAwrD9+8GoZc9UmEtS2Jyx myKkUIqEYWIdgyfjeyT+m6xioj8gUfmq7xSNU37YekbGBKq5ZSuZaSgqbTQWKpPXchrG qjuJqB0xi2/LBe5zFZuUiy2jVnqK8pF55Q4yY= Original-Received: by 10.142.238.10 with SMTP id l10mr3769214wfh.90.1301340572838; Mon, 28 Mar 2011 12:29:32 -0700 (PDT) Original-Received: from [0.0.0.0] (c-67-183-23-114.hsd1.wa.comcast.net [67.183.23.114]) by mx.google.com with ESMTPS id w32sm6228102wfh.7.2011.03.28.12.29.31 (version=SSLv3 cipher=OTHER); Mon, 28 Mar 2011 12:29:31 -0700 (PDT) User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.15) Gecko/20110303 Thunderbird/3.1.9 In-Reply-To: <83bp0vrszf.fsf@gnu.org> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 209.85.210.41 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:137797 Archived-At: On 3/28/2011 11:37 AM, Eli Zaretskii wrote: >>>> Killing Emacs destroys any transient state. The last-resort-quit >>>> approach doesn't. >>> You originally said "save edits or debug Emacs", see above. >>> >>> What transient state are we talking about? >> I'm talking about any state not already written out to more permanent >> storage --- that includes not only unsaved buffer contents, but tramp >> sessions, window configurations, various histories, and so on. > Isn't that part of handling a fatal signal? Right --- but with a patch like mine, a lockup in font-lock or some other obscure corner of the codebase isn't fatal anymore. >> (Speaking of debugging bytecode, by the way: would it be feasible to >> someday provide the ability to step through compiled functions >> bytecode-by-bytecode?) > I'm not sure I understand what you are suggesting here. What I would > love is the ability to "disassemble" a Lisp backtrace, so that any > byte codes are converted into human-readable Lisp (or something > similar). Perhaps there's already such a thing, who knows? There isn't, to my knowledge. What I'd like to see is the ability to view and step through Emacs disassembled bytecode the same way we can view and step through disassembled machine code in gdb. I don't know how complex the implementation of such a feature would be, but we do have a disassembled in Emacs to start. >>>> can let users recover work and provide more detailed bug reports, as >>>> well as help us ferret out the cause of hard-to-reproduce lockups in >>>> font-lock code without having to run under a debugger all the time. >>> I'd like to hear what work can be recovered this way that is not >>> recovered by auto-save at fatal signal time. >> Auto-save doesn't run continuously, and not everyone has it turned on. > I meant the automatic auto-save triggered by catching a fatal signal. > See emacs.c:fatal_error_signal. Ah, I didn't know about that. It'd still be nice to be able to recover a hung Emacs process instead of killing it, and my point about having to restore other transient state still applies. >> What Lisp-level method do you propose for breaking out of (let >> ((inhibit-quit t)) (while t)) ? > This isn't an interesting example. I was talking about font-lock, > which I understand was the primary motivation for this patch. > Font-lock does not have such useless loops (I hope ;-). It shouldn't, but there are and always will be bugs that result in essentially identical behavior. > I was asking about whatever you had in mind when you wished you could > implement such a feature without introducing additional machinery. > You tell me. We want to be able to interrupt code running in a tight loop in situations when quit would normally be disabled, such as during redisplay. Quit is disabled during background work for a good reason, so we shouldn't just rely on the normal quit mechanism. Thus, we need some other way of signaling Emacs. If events aren't being delivered, as in a tight loop, then commands won't be run and anything bound normally to some keymap will be useless. One way of delivering an event to Emacs that does not depend on the command loop is the signal mechanism. There is a facility to bind a command to a signal via `special-event-map'. This facility is not useful for our purposes here because it works by having signals post events to the command loop, which, as we've already established, is not running. Except for the quit mechanism itself, there is no way to configure Emacs to react asynchronously to some event when the command loop will not run, and so there is no way to break into a wedged Emacs. Any implementation of this functionality will require changes to the C core. We have a few options for the implementation strategy: 1) Bind (debug) to a signal in special-event-map, and send Emacs that signal to interrupt it. We would have to change the core such that it would run commands associated with pending signals during QUIT. 2) Create a quit-like mechanism in all the ports that would listen for a special character. This character would be interpreted like C-g today, except that it would unconditionally break into the debugger. 3) Provide an explicit way to configure the C core to break in response to a signal, then send that signal to interrupt Emacs. This is the approach I've implemented. Option 1 wont work because code today doesn't expect to arbitrary Lisp code to run wherever there is a QUIT, and running a command implies just that. Option 2 is more invasive, steals a key, and doesn't add any expressive power. I've implemented option 3, and it works well enough so far.