Opened 13 years ago

Closed 13 years ago

#421 closed defect (fixed)

proof-shell-exit raises an exception "Buffer foo.v has no process"

Reported by: courtieu Owned by: coquser
Priority: critical Milestone: PG-Emacs-4.1
Component: 2:pg-emacs Keywords: shell exit
Cc:

Description

Hello, here is how to reproduce the bug:

open a coq file (say toto.v). proof script one line. hit C-c C-x <enter> yes <enter>

and you get this:

Debugger entered--Lisp error: (error "Buffer toto.v has no process")

process-send-eof() scomint-send-eof() (if proof-shell-quit-cmd (scomint-send-string proc (concat proof-shell-quit-cmd "\n")) (scomint-send-eof)) (catch (quote exited) (set-process-sentinel proc (lambda ... ...)) (proof-deactivate-scripting-auto) (proof-shell-wait (proof-ass quit-timeout)) (if proof-shell-quit-cmd (scomint-send-string proc ...) (scomint-send-eof)) (let (... ...) (while ... ... ...)) (when (memq ... ...) (message "%s, cleaning up and exiting...killing process" bufname) (kill-process proc))) (progn (catch (quote exited) (set-process-sentinel proc ...) (proof-deactivate-scripting-auto) (proof-shell-wait ...) (if proof-shell-quit-cmd ... ...) (let ... ...) (when ... ... ...)) (set-process-sentinel proc nil)) (if (and alive proc) (progn (catch ... ... ... ... ... ... ...) (set-process-sentinel proc nil))) (when (and alive proc) (catch (quote exited) (set-process-sentinel proc ...) (proof-deactivate-scripting-auto) (proof-shell-wait ...) (if proof-shell-quit-cmd ... ...) (let ... ...) (when ... ... ...)) (set-process-sentinel proc nil)) (let* ((alive ...) (proc ...) (bufname ...)) (message "%s, cleaning up and exiting..." bufname) (redisplay t) (when (and alive proc) (catch ... ... ... ... ... ... ...) (set-process-sentinel proc nil)) (proof-script-remove-all-spans-and-deactivate) (proof-shell-clear-state) (run-hooks (quote proof-shell-kill-function-hooks)) (if (and proof-multiple-frames-enable proof-shell-fiddle-frames) (proof-delete-other-frames)) (let (...) (dolist ... ...)) (message "%s exited." bufname)) proof-shell-kill-function() kill-buffer(#<killed buffer>) (let ((kill-buffer-query-functions nil)) (kill-buffer proof-shell-buffer)) (progn (let (...) (kill-buffer proof-shell-buffer)) (setq proof-shell-buffer nil)) (if (or dont-ask (yes-or-no-p ...)) (progn (let ... ...) (setq proof-shell-buffer nil))) (when (or dont-ask (yes-or-no-p ...)) (let (...) (kill-buffer proof-shell-buffer)) (setq proof-shell-buffer nil)) (if (buffer-live-p proof-shell-buffer) (when (or dont-ask ...) (let ... ...) (setq proof-shell-buffer nil)) (error "No proof shell buffer to kill!")) proof-shell-exit() call-interactively(proof-shell-exit nil nil)

Change History (5)

comment:1 Changed 13 years ago by coquser

Owner: changed from David Aspinall to coquser
Status: newaccepted

The problem is coq-switch-buffer-kill-proof-shell and that proof-shell-kill-function does not take into account that a prover might get killed when scripting is deactivated.

Before kill-buffer inside proof-shell-exit actually kills the buffer and the process, it runs proof-shell-kill-function as part of the kill-buffer-hook's. proof-shell-kill-function deactivates scripting and therefore proof-deactivate-scripting-hook is run. For Coq this latter hook contains coq-switch-buffer-kill-proof-shell, which calls proof-shell-exit again. This looks like an infinite recursion, but before proof-deactivate-scripting-hook is run proof-script-buffer is set to nil, therefore the second recursive call to proof-deactivate-scripting does nothing.

The nested instance of proof-shell-kill-function kills Coq. However, the top-level instance of proof-shell-kill-function is not aware of this and tries to terminate Coq again, after proof-deactivate-scripting-auto returned.

I see two possible ways to fix this:

  1. Inside proof-shell-kill-function set a global variable proof-shell-exit-in-progress. When coq-switch-buffer-kill-proof-shell sees this it refrains from calling proof-shell-exit recursively.
  1. Change proof-shell-kill-function such that it can cope with the fact that provers die when scripting is deactivated.

Bye,

Hendrik

comment:2 Changed 13 years ago by David Aspinall

Hi Hendrik, thanks for the diagnosis. Of course deactivate scripting was originally assumed not to kill the process. But now it may do for Coq, it seems best to try to make the code cope with this happening for any prover, so the second option would be the most robust. Would you like to propose/commit a patch? - David

comment:3 Changed 13 years ago by coquser

I proposed solution 1 mainly because I think that the recursive call of proof-shell-exit is bad design.

Note that solution 1 would also work for any other prover, if they only respect the protocol to wrap calls to proof-shell-exit like

(unless proof-shell-exit-in-progress
  (proof-shell-exit t))

Bye,

Hendrik

comment:4 Changed 13 years ago by David Aspinall

OK, I'm happy for you to commit that solution. Thanks - David.

comment:5 Changed 13 years ago by coquser

Resolution: fixed
Status: acceptedclosed

Fixed with solution 1.

Hendrik

Note: See TracTickets for help on using tickets.