1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2025-01-01 11:14:55 +00:00

Delete the gdb-inferior pty when the gdb process exits.

* lisp/progmodes/gdb-mi.el (gdb-inferior-io--maybe-delete-pty): New
function to call delete-process on the gdb-inferior buffer's pty.
(gdb-reset): Use it, instead of relying on kill-buffer to kill the
pty process.
(gdb-update): New arg to suppress talking to the gdb process.
(gdb-done-or-error): Use it.
(gdb-stopped-functions): Rename from gdb-stopped-hooks.
(gdb): Call gdb-inferior-io--maybe-delete-pty as a workaround for
sentinel not being called.

* lisp/comint.el (make-comint-in-buffer, comint-exec): Doc fix.

Fixes: debbugs:11273
This commit is contained in:
Chong Yidong 2012-04-19 16:09:30 +08:00
parent c5467d73ae
commit b668fa6eb0
3 changed files with 86 additions and 34 deletions

View File

@ -1,3 +1,17 @@
2012-04-19 Chong Yidong <cyd@gnu.org>
* progmodes/gdb-mi.el (gdb-inferior-io--maybe-delete-pty): New
function to call delete-process on the gdb-inferior buffer's pty.
(gdb-reset): Use it, instead of relying on kill-buffer to kill the
pty process (Bug#11273).
(gdb-update): New arg to suppress talking to the gdb process.
(gdb-done-or-error): Use it.
(gdb-stopped-functions): Rename from gdb-stopped-hooks.
(gdb): Call gdb-inferior-io--maybe-delete-pty as a workaround for
sentinel not being called.
* comint.el (make-comint-in-buffer, comint-exec): Doc fix.
2012-04-18 Chong Yidong <cyd@gnu.org>
* progmodes/grep.el (grep, rgrep): Doc fix (Bug#11268).

View File

@ -699,16 +699,21 @@ BUFFER can be either a buffer or the name of one."
(defun make-comint-in-buffer (name buffer program &optional startfile &rest switches)
"Make a Comint process NAME in BUFFER, running PROGRAM.
If BUFFER is nil, it defaults to NAME surrounded by `*'s.
PROGRAM should be either a string denoting an executable program to create
via `start-file-process', or a cons pair of the form (HOST . SERVICE) denoting
a TCP connection to be opened via `open-network-stream'. If there is already
a running process in that buffer, it is not restarted. Optional fourth arg
STARTFILE is the name of a file, whose contents are sent to the
process as its initial input.
If there is a running process in BUFFER, it is not restarted.
PROGRAM should be one of the following:
- a string, denoting an executable program to create via
`start-file-process'
- a cons pair of the form (HOST . SERVICE), denoting a TCP
connection to be opened via `open-network-stream'
- nil, denoting a newly-allocated pty.
Optional fourth arg STARTFILE is the name of a file, whose
contents are sent to the process as its initial input.
If PROGRAM is a string, any more args are arguments to PROGRAM.
Returns the (possibly newly created) process buffer."
Return the (possibly newly created) process buffer."
(or (fboundp 'start-file-process)
(error "Multi-processing is not supported for this system"))
(setq buffer (get-buffer-create (or buffer (concat "*" name "*"))))
@ -752,9 +757,18 @@ See `make-comint' and `comint-exec'."
(defun comint-exec (buffer name command startfile switches)
"Start up a process named NAME in buffer BUFFER for Comint modes.
Runs the given COMMAND with SWITCHES, and initial input from STARTFILE.
Blasts any old process running in the buffer. Doesn't set the buffer mode.
You can use this to cheaply run a series of processes in the same Comint
buffer. The hook `comint-exec-hook' is run after each exec."
COMMAND should be one of the following:
- a string, denoting an executable program to create via
`start-file-process'
- a cons pair of the form (HOST . SERVICE), denoting a TCP
connection to be opened via `open-network-stream'
- nil, denoting a newly-allocated pty.
This function blasts any old process running in the buffer, and
does not set the buffer mode. You can use this to cheaply run a
series of processes in the same Comint buffer. The hook
`comint-exec-hook' is run after each exec."
(with-current-buffer buffer
(let ((proc (get-buffer-process buffer))) ; Blast any old process.
(if proc (delete-process proc)))

View File

@ -375,9 +375,8 @@ Emacs always switches to the thread which caused the stop."
:version "23.2"
:link '(info-link "(gdb)GDB/MI Async Records"))
(defcustom gdb-stopped-hooks nil
"This variable holds a list of functions to be called whenever
GDB stops.
(defcustom gdb-stopped-functions nil
"List of functions called whenever GDB stops.
Each function takes one argument, a parsed MI response, which
contains fields of corresponding MI *stopped async record:
@ -818,6 +817,11 @@ detailed description of this mode.
nil 'local)
(local-set-key "\C-i" 'completion-at-point)
;; FIXME: Under some circumstances, `gud-sentinel' apparently does
;; not get called when the gdb process is killed (Bug#11273).
(add-hook 'post-command-hook 'gdb-inferior-io--maybe-delete-pty
nil t)
(setq gdb-first-prompt t)
(setq gud-running nil)
@ -1510,6 +1514,14 @@ DOC is an optional documentation string."
(gdb-display-buffer
(gdb-get-buffer-create 'gdb-inferior-io) t))
(defun gdb-inferior-io--maybe-delete-pty ()
(let ((proc (get-buffer-process gud-comint-buffer))
(inf-pty (get-process "gdb-inferior")))
(and (or (null proc)
(memq (process-status proc) '(exit signal)))
inf-pty
(delete-process inf-pty))))
(defconst gdb-frame-parameters
'((height . 14) (width . 80)
(unsplittable . t)
@ -1746,24 +1758,27 @@ If `gdb-thread-number' is nil, just wrap NAME in asterisks."
(setq gdb-output-sink 'user)
(setq gdb-pending-triggers nil))
(defun gdb-update ()
"Update buffers showing status of debug session."
(defun gdb-update (&optional no-proc)
"Update buffers showing status of debug session.
If NO-PROC is non-nil, do not try to contact the GDB process."
(when gdb-first-prompt
(gdb-force-mode-line-update
(propertize "initializing..." 'face font-lock-variable-name-face))
(gdb-init-1)
(setq gdb-first-prompt nil))
(gdb-get-main-selected-frame)
(unless no-proc
(gdb-get-main-selected-frame))
;; We may need to update gdb-threads-list so we can use
(gdb-get-buffer-create 'gdb-threads-buffer)
;; gdb-break-list is maintained in breakpoints handler
(gdb-get-buffer-create 'gdb-breakpoints-buffer)
(gdb-emit-signal gdb-buf-publisher 'update)
(unless no-proc
(gdb-emit-signal gdb-buf-publisher 'update))
(gdb-get-changed-registers)
(when (and (boundp 'speedbar-frame) (frame-live-p speedbar-frame))
(dolist (var gdb-var-list)
(setcar (nthcdr 5 var) nil))
@ -2045,7 +2060,7 @@ current thread and update GDB buffers."
;; In all-stop this updates gud-running properly as well.
(gdb-update)
(setq gdb-first-done-or-error nil))
(run-hook-with-args 'gdb-stopped-hooks result)))
(run-hook-with-args 'gdb-stopped-functions result)))
;; Remove the trimmings from log stream containing debugging messages
;; being produced by GDB's internals, use warning face and send to GUD
@ -2085,23 +2100,28 @@ current thread and update GDB buffers."
(setq gdb-output-sink 'emacs))
(gdb-clear-partial-output)
(when gdb-first-done-or-error
(unless (or token-number gud-running)
(setq gdb-filter-output (concat gdb-filter-output gdb-prompt-name)))
(gdb-update)
(setq gdb-first-done-or-error nil))
(setq gdb-filter-output
(gdb-concat-output gdb-filter-output output-field))
;; The process may already be dead (e.g. C-d at the gdb prompt).
(let* ((proc (get-buffer-process gud-comint-buffer))
(no-proc (or (null proc)
(memq (process-status proc) '(exit signal)))))
(if token-number
(progn
(with-current-buffer
(gdb-get-buffer-create 'gdb-partial-output-buffer)
(funcall
(cdr (assoc (string-to-number token-number) gdb-handler-alist))))
(setq gdb-handler-alist
(assq-delete-all token-number gdb-handler-alist)))))
(when gdb-first-done-or-error
(unless (or token-number gud-running no-proc)
(setq gdb-filter-output (concat gdb-filter-output gdb-prompt-name)))
(gdb-update no-proc)
(setq gdb-first-done-or-error nil))
(setq gdb-filter-output
(gdb-concat-output gdb-filter-output output-field))
(when token-number
(with-current-buffer
(gdb-get-buffer-create 'gdb-partial-output-buffer)
(funcall
(cdr (assoc (string-to-number token-number) gdb-handler-alist))))
(setq gdb-handler-alist
(assq-delete-all token-number gdb-handler-alist)))))
(defun gdb-concat-output (so-far new)
(cond
@ -4105,9 +4125,13 @@ This arrangement depends on the value of `gdb-many-windows'."
(gud-find-file gdb-main-file)))
(setq gdb-source-window win)))))
;; Called from `gud-sentinel' in gud.el:
(defun gdb-reset ()
"Exit a debugging session cleanly.
Kills the gdb buffers, and resets variables and the source buffers."
;; The gdb-inferior buffer has a pty hooked up to the main gdb
;; process. This pty must be deleted explicitly.
(gdb-inferior-io--maybe-delete-pty)
(dolist (buffer (buffer-list))
(unless (eq buffer gud-comint-buffer)
(with-current-buffer buffer