1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2025-01-19 18:13: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> 2012-04-18 Chong Yidong <cyd@gnu.org>
* progmodes/grep.el (grep, rgrep): Doc fix (Bug#11268). * 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) (defun make-comint-in-buffer (name buffer program &optional startfile &rest switches)
"Make a Comint process NAME in BUFFER, running PROGRAM. "Make a Comint process NAME in BUFFER, running PROGRAM.
If BUFFER is nil, it defaults to NAME surrounded by `*'s. If BUFFER is nil, it defaults to NAME surrounded by `*'s.
PROGRAM should be either a string denoting an executable program to create If there is a running process in BUFFER, it is not restarted.
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 PROGRAM should be one of the following:
a running process in that buffer, it is not restarted. Optional fourth arg - a string, denoting an executable program to create via
STARTFILE is the name of a file, whose contents are sent to the `start-file-process'
process as its initial input. - 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. 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) (or (fboundp 'start-file-process)
(error "Multi-processing is not supported for this system")) (error "Multi-processing is not supported for this system"))
(setq buffer (get-buffer-create (or buffer (concat "*" name "*")))) (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) (defun comint-exec (buffer name command startfile switches)
"Start up a process named NAME in buffer BUFFER for Comint modes. "Start up a process named NAME in buffer BUFFER for Comint modes.
Runs the given COMMAND with SWITCHES, and initial input from STARTFILE. 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 COMMAND should be one of the following:
buffer. The hook `comint-exec-hook' is run after each exec." - 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 (with-current-buffer buffer
(let ((proc (get-buffer-process buffer))) ; Blast any old process. (let ((proc (get-buffer-process buffer))) ; Blast any old process.
(if proc (delete-process proc))) (if proc (delete-process proc)))

View File

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