25 |
|
|
26 |
;;; Commentary: |
;;; Commentary: |
27 |
|
|
28 |
;; This mode acts as a graphical user interface to GDB. You can interact with |
;; This mode acts as a graphical user interface to GDB. You can interact with |
29 |
;; GDB through the GUD buffer in the usual way, but there are also further |
;; GDB through the GUD buffer in the usual way, but there are also further |
30 |
;; buffers which control the execution and describe the state of your program. |
;; buffers which control the execution and describe the state of your program. |
31 |
;; It separates the input/output of your program from that of GDB, if |
;; It separates the input/output of your program from that of GDB, if |
32 |
;; required, and watches expressions in the speedbar. It also uses features of |
;; required, and watches expressions in the speedbar. It also uses features of |
33 |
;; Emacs 21 such as the fringe/display margin for breakpoints, and the toolbar |
;; Emacs 21 such as the fringe/display margin for breakpoints, and the toolbar |
34 |
;; (see the GDB Graphical Interface section in the Emacs info manual). |
;; (see the GDB Graphical Interface section in the Emacs info manual). |
35 |
|
|
36 |
;; Start the debugger with M-x gdba. |
;; Start the debugger with M-x gdba. |
37 |
|
|
38 |
;; This file has evolved from gdba.el from GDB 5.0 written by Tom Lord and Jim |
;; This file has evolved from gdba.el from GDB 5.0 written by Tom Lord and Jim |
39 |
;; Kingdon and uses GDB's annotation interface. You don't need to know about |
;; Kingdon and uses GDB's annotation interface. You don't need to know about |
40 |
;; annotations to use this mode as a debugger, but if you are interested |
;; annotations to use this mode as a debugger, but if you are interested |
41 |
;; developing the mode itself, then see the Annotations section in the GDB |
;; developing the mode itself, then see the Annotations section in the GDB |
42 |
;; info manual. |
;; info manual. |
43 |
;; |
;; |
44 |
;; GDB developers plan to make the annotation interface obsolete. A new |
;; GDB developers plan to make the annotation interface obsolete. A new |
45 |
;; interface called GDB/MI (machine interface) has been designed to replace |
;; interface called GDB/MI (machine interface) has been designed to replace |
46 |
;; it. Some GDB/MI commands are used in this file through the CLI command |
;; it. Some GDB/MI commands are used in this file through the CLI command |
47 |
;; 'interpreter mi <mi-command>'. A file called gdb-mi.el is included in the |
;; 'interpreter mi <mi-command>'. A file called gdb-mi.el is included in the |
48 |
;; GDB repository for future releases (6.2 onwards) that uses GDB/MI as the |
;; GDB repository for future releases (6.2 onwards) that uses GDB/MI as the |
49 |
;; primary interface to GDB. It is still under development and is part of a |
;; primary interface to GDB. It is still under development and is part of a |
50 |
;; process to migrate Emacs from annotations to GDB/MI. |
;; process to migrate Emacs from annotations to GDB/MI. |
51 |
;; |
;; |
52 |
;; Known Bugs: |
;; Known Bugs: |
63 |
(defvar gdb-current-language nil) |
(defvar gdb-current-language nil) |
64 |
(defvar gdb-view-source t "Non-nil means that source code can be viewed.") |
(defvar gdb-view-source t "Non-nil means that source code can be viewed.") |
65 |
(defvar gdb-selected-view 'source "Code type that user wishes to view.") |
(defvar gdb-selected-view 'source "Code type that user wishes to view.") |
66 |
(defvar gdb-var-list nil "List of variables in watch window") |
(defvar gdb-var-list nil "List of variables in watch window.") |
67 |
(defvar gdb-var-changed nil "Non-nil means that gdb-var-list has changed.") |
(defvar gdb-var-changed nil "Non-nil means that gdb-var-list has changed.") |
68 |
(defvar gdb-buffer-type nil) |
(defvar gdb-buffer-type nil) |
69 |
(defvar gdb-overlay-arrow-position nil) |
(defvar gdb-overlay-arrow-position nil) |
85 |
If `gdb-many-windows' is t, regardless of the value of |
If `gdb-many-windows' is t, regardless of the value of |
86 |
`gdb-show-main', the layout below will appear unless |
`gdb-show-main', the layout below will appear unless |
87 |
`gdb-use-inferior-io-buffer' is nil when the source buffer |
`gdb-use-inferior-io-buffer' is nil when the source buffer |
88 |
occupies the full width of the frame. Keybindings are given in |
occupies the full width of the frame. Keybindings are given in |
89 |
relevant buffer. |
relevant buffer. |
90 |
|
|
91 |
Watch expressions appear in the speedbar/slowbar. |
Watch expressions appear in the speedbar/slowbar. |
92 |
|
|
93 |
The following interactive lisp functions help control operation : |
The following commands help control operation : |
94 |
|
|
95 |
`gdb-many-windows' - Toggle the number of windows gdb uses. |
`gdb-many-windows' - Toggle the number of windows gdb uses. |
96 |
`gdb-restore-windows' - To restore the window layout. |
`gdb-restore-windows' - To restore the window layout. |
120 |
RET gdb-frames-select | SPC gdb-toggle-breakpoint |
RET gdb-frames-select | SPC gdb-toggle-breakpoint |
121 |
| RET gdb-goto-breakpoint |
| RET gdb-goto-breakpoint |
122 |
| d gdb-delete-breakpoint |
| d gdb-delete-breakpoint |
123 |
--------------------------------------------------------------------- |
---------------------------------------------------------------------" |
|
" |
|
124 |
;; |
;; |
125 |
(interactive (list (gud-query-cmdline 'gdba))) |
(interactive (list (gud-query-cmdline 'gdba))) |
126 |
;; |
;; |
209 |
(run-hooks 'gdba-mode-hook)) |
(run-hooks 'gdba-mode-hook)) |
210 |
|
|
211 |
(defcustom gdb-use-colon-colon-notation nil |
(defcustom gdb-use-colon-colon-notation nil |
212 |
"Non-nil means use FUNCTION::VARIABLE format to display variables in the |
"If non-nil use FUN::VAR format to display variables in the speedbar." ; |
|
speedbar." |
|
213 |
:type 'boolean |
:type 'boolean |
214 |
:group 'gud) |
:group 'gud) |
215 |
|
|
374 |
(setq gdb-var-changed t)))))) |
(setq gdb-var-changed t)))))) |
375 |
|
|
376 |
(defun gdb-edit-value (text token indent) |
(defun gdb-edit-value (text token indent) |
377 |
"Assign a value to a variable displayed in the speedbar" |
"Assign a value to a variable displayed in the speedbar." |
378 |
(let* ((var (nth (- (count-lines (point-min) (point)) 2) gdb-var-list)) |
(let* ((var (nth (- (count-lines (point-min) (point)) 2) gdb-var-list)) |
379 |
(varnum (cadr var)) (value)) |
(varnum (cadr var)) (value)) |
380 |
(setq value (read-string "New value: ")) |
(setq value (read-string "New value: ")) |
387 |
'ignore)))) |
'ignore)))) |
388 |
|
|
389 |
(defcustom gdb-show-changed-values t |
(defcustom gdb-show-changed-values t |
390 |
"Non-nil means use font-lock-warning-face to display values that have |
"If non-nil highlight values that have recently changed in the speedbar. |
391 |
recently changed in the speedbar." |
The highlighting is done with `font-lock-warning-face'." |
392 |
:type 'boolean |
:type 'boolean |
393 |
:group 'gud) |
:group 'gud) |
394 |
|
|
420 |
"The disposition of the output of the current gdb command. |
"The disposition of the output of the current gdb command. |
421 |
Possible values are these symbols: |
Possible values are these symbols: |
422 |
|
|
423 |
user -- gdb output should be copied to the GUD buffer |
`user' -- gdb output should be copied to the GUD buffer |
424 |
for the user to see. |
for the user to see. |
425 |
|
|
426 |
inferior -- gdb output should be copied to the inferior-io buffer |
`inferior' -- gdb output should be copied to the inferior-io buffer |
427 |
|
|
428 |
pre-emacs -- output should be ignored util the post-prompt |
`pre-emacs' -- output should be ignored util the post-prompt |
429 |
annotation is received. Then the output-sink |
annotation is received. Then the output-sink |
430 |
becomes:... |
becomes:... |
431 |
emacs -- output should be collected in the partial-output-buffer |
`emacs' -- output should be collected in the partial-output-buffer |
432 |
for subsequent processing by a command. This is the |
for subsequent processing by a command. This is the |
433 |
disposition of output generated by commands that |
disposition of output generated by commands that |
434 |
gdb mode sends to gdb on its own behalf. |
gdb mode sends to gdb on its own behalf. |
435 |
post-emacs -- ignore output until the prompt annotation is |
`post-emacs' -- ignore output until the prompt annotation is |
436 |
received, then go to USER disposition. |
received, then go to USER disposition. |
437 |
|
|
438 |
gdba (gdb-ui.el) uses all five values, gdbmi (gdb-mi.el) only two |
gdba (gdb-ui.el) uses all five values, gdbmi (gdb-mi.el) only two |
439 |
(user and emacs).") |
\(`user' and `emacs').") |
440 |
|
|
441 |
(defvar gdb-current-item nil |
(defvar gdb-current-item nil |
442 |
"The most recent command item sent to gdb.") |
"The most recent command item sent to gdb.") |
617 |
|
|
618 |
(defun gdb-send (proc string) |
(defun gdb-send (proc string) |
619 |
"A comint send filter for gdb. |
"A comint send filter for gdb. |
620 |
This filter may simply queue output for a later time." |
This filter may simply queue input for a later time." |
621 |
(if gud-running |
(if gud-running |
622 |
(process-send-string proc (concat string "\n")) |
(process-send-string proc (concat string "\n")) |
623 |
(gdb-enqueue-input (concat string "\n")))) |
(gdb-enqueue-input (concat string "\n")))) |
703 |
(setq gdb-current-item item) |
(setq gdb-current-item item) |
704 |
(with-current-buffer gud-comint-buffer |
(with-current-buffer gud-comint-buffer |
705 |
(if (eq gud-minor-mode 'gdba) |
(if (eq gud-minor-mode 'gdba) |
706 |
(progn |
(if (stringp item) |
|
(if (stringp item) |
|
|
(progn |
|
|
(setq gdb-output-sink 'user) |
|
|
(process-send-string (get-buffer-process gud-comint-buffer) item)) |
|
707 |
(progn |
(progn |
708 |
(gdb-clear-partial-output) |
(setq gdb-output-sink 'user) |
709 |
(setq gdb-output-sink 'pre-emacs) |
(process-send-string (get-buffer-process gud-comint-buffer) item)) |
710 |
(process-send-string (get-buffer-process gud-comint-buffer) |
(progn |
711 |
(car item))))) |
(gdb-clear-partial-output) |
712 |
; case: eq gud-minor-mode 'gdbmi |
(setq gdb-output-sink 'pre-emacs) |
713 |
|
(process-send-string (get-buffer-process gud-comint-buffer) |
714 |
|
(car item)))) |
715 |
|
;; case: eq gud-minor-mode 'gdbmi |
716 |
(gdb-clear-partial-output) |
(gdb-clear-partial-output) |
717 |
(setq gdb-output-sink 'emacs) |
(setq gdb-output-sink 'emacs) |
718 |
(process-send-string (get-buffer-process gud-comint-buffer) |
(process-send-string (get-buffer-process gud-comint-buffer) |
719 |
(car item))))) |
(car item))))) |
720 |
|
|
721 |
(defun gdb-pre-prompt (ignored) |
(defun gdb-pre-prompt (ignored) |
722 |
"An annotation handler for `pre-prompt'. This terminates the collection of |
"An annotation handler for `pre-prompt'. |
723 |
output from a previous command if that happens to be in effect." |
This terminates the collection of output from a previous command if that |
724 |
|
happens to be in effect." |
725 |
(let ((sink gdb-output-sink)) |
(let ((sink gdb-output-sink)) |
726 |
(cond |
(cond |
727 |
((eq sink 'user) t) |
((eq sink 'user) t) |
759 |
(setq gdb-prompting t)) |
(setq gdb-prompting t)) |
760 |
|
|
761 |
(defun gdb-starting (ignored) |
(defun gdb-starting (ignored) |
762 |
"An annotation handler for `starting'. This says that I/O for the |
"An annotation handler for `starting'. |
763 |
subprocess is now the program being debugged, not GDB." |
This says that I/O for the subprocess is now the program being debugged, |
764 |
|
not GDB." |
765 |
(let ((sink gdb-output-sink)) |
(let ((sink gdb-output-sink)) |
766 |
(cond |
(cond |
767 |
((eq sink 'user) |
((eq sink 'user) |
772 |
(t (error "Unexpected `starting' annotation"))))) |
(t (error "Unexpected `starting' annotation"))))) |
773 |
|
|
774 |
(defun gdb-stopping (ignored) |
(defun gdb-stopping (ignored) |
775 |
"An annotation handler for `exited' and other annotations which say that I/O |
"An annotation handler for `exited' and other annotations. |
776 |
for the subprocess is now GDB, not the program being debugged." |
They say that I/O for the subprocess is now GDB, not the program |
777 |
|
being debugged." |
778 |
(if gdb-use-inferior-io-buffer |
(if gdb-use-inferior-io-buffer |
779 |
(let ((sink gdb-output-sink)) |
(let ((sink gdb-output-sink)) |
780 |
(cond |
(cond |
792 |
(t (error "Unexpected frame-begin annotation (%S)" sink))))) |
(t (error "Unexpected frame-begin annotation (%S)" sink))))) |
793 |
|
|
794 |
(defun gdb-stopped (ignored) |
(defun gdb-stopped (ignored) |
795 |
"An annotation handler for `stopped'. It is just like gdb-stopping, except |
"An annotation handler for `stopped'. |
796 |
that if we already set the output sink to 'user in gdb-stopping, that is fine." |
It is just like `gdb-stopping', except that if we already set the output |
797 |
|
sink to `user' in `gdb-stopping', that is fine." |
798 |
(setq gud-running nil) |
(setq gud-running nil) |
799 |
(let ((sink gdb-output-sink)) |
(let ((sink gdb-output-sink)) |
800 |
(cond |
(cond |
804 |
(t (error "Unexpected stopped annotation"))))) |
(t (error "Unexpected stopped annotation"))))) |
805 |
|
|
806 |
(defun gdb-post-prompt (ignored) |
(defun gdb-post-prompt (ignored) |
807 |
"An annotation handler for `post-prompt'. This begins the collection of |
"An annotation handler for `post-prompt'. |
808 |
output from the current command if that happens to be appropriate." |
This begins the collection of output from the current command if that |
809 |
|
happens to be appropriate." |
810 |
(if (not gdb-pending-triggers) |
(if (not gdb-pending-triggers) |
811 |
(progn |
(progn |
812 |
(gdb-get-current-frame) |
(gdb-get-current-frame) |
834 |
(error "Phase error in gdb-post-prompt (got %s)" sink))))) |
(error "Phase error in gdb-post-prompt (got %s)" sink))))) |
835 |
|
|
836 |
(defun gud-gdba-marker-filter (string) |
(defun gud-gdba-marker-filter (string) |
837 |
"A gud marker filter for gdb. Handle a burst of output from GDB." |
"A gud marker filter for gdb. Handle a burst of output from GDB." |
838 |
(if gdb-enable-debug-log (push (cons 'recv string) gdb-debug-log)) |
(if gdb-enable-debug-log (push (cons 'recv string) gdb-debug-log)) |
839 |
;; Recall the left over gud-marker-acc from last time |
;; Recall the left over gud-marker-acc from last time |
840 |
(setq gud-marker-acc (concat gud-marker-acc string)) |
(setq gud-marker-acc (concat gud-marker-acc string)) |
1067 |
"PBM data used for disabled breakpoint icon.") |
"PBM data used for disabled breakpoint icon.") |
1068 |
|
|
1069 |
(defvar breakpoint-enabled-icon nil |
(defvar breakpoint-enabled-icon nil |
1070 |
"Icon for enabled breakpoint in display margin") |
"Icon for enabled breakpoint in display margin.") |
1071 |
|
|
1072 |
(defvar breakpoint-disabled-icon nil |
(defvar breakpoint-disabled-icon nil |
1073 |
"Icon for disabled breakpoint in display margin") |
"Icon for disabled breakpoint in display margin.") |
1074 |
|
|
1075 |
;; Bitmap for breakpoint in fringe |
;; Bitmap for breakpoint in fringe |
1076 |
(define-fringe-bitmap 'breakpoint |
(define-fringe-bitmap 'breakpoint |
1135 |
(if (gdb-get-buffer 'gdb-assembler-buffer) (gdb-assembler-custom))) |
(if (gdb-get-buffer 'gdb-assembler-buffer) (gdb-assembler-custom))) |
1136 |
|
|
1137 |
(defun gdb-mouse-toggle-breakpoint (event) |
(defun gdb-mouse-toggle-breakpoint (event) |
1138 |
"Toggle breakpoint in left fringe/margin with mouse click" |
"Toggle breakpoint in left fringe/margin with mouse click." |
1139 |
(interactive "e") |
(interactive "e") |
1140 |
(mouse-minibuffer-check event) |
(mouse-minibuffer-check event) |
1141 |
(let ((posn (event-end event))) |
(let ((posn (event-end event))) |
1720 |
(other-window 1)) |
(other-window 1)) |
1721 |
|
|
1722 |
(defcustom gdb-many-windows nil |
(defcustom gdb-many-windows nil |
1723 |
"Nil (the default value) means just pop up the GUD buffer |
"Nil means just pop up the GUD buffer unless `gdb-show-main' is t. |
1724 |
unless `gdb-show-main' is t. In this case it starts with two |
In this case it starts with two windows: one displaying the GUD |
1725 |
windows: one displaying the GUD buffer and the other with the |
buffer and the other with the source file with the main routine |
1726 |
source file with the main routine of the inferior. Non-nil means |
of the inferior. Non-nil means display the layout shown for |
1727 |
display the layout shown for `gdba'." |
`gdba'." |
1728 |
:type 'boolean |
:type 'boolean |
1729 |
:group 'gud) |
:group 'gud) |
1730 |
|
|
1762 |
(other-window 1))) |
(other-window 1))) |
1763 |
|
|
1764 |
(defun gdb-reset () |
(defun gdb-reset () |
1765 |
"Exit a debugging session cleanly by killing the gdb buffers and resetting |
"Exit a debugging session cleanly. |
1766 |
the source buffers." |
Kills the gdb buffers and resets the source buffers." |
1767 |
(dolist (buffer (buffer-list)) |
(dolist (buffer (buffer-list)) |
1768 |
(unless (eq buffer gud-comint-buffer) |
(unless (eq buffer gud-comint-buffer) |
1769 |
(with-current-buffer buffer |
(with-current-buffer buffer |