diff options
Diffstat (limited to 'lisp/progmodes/gdb-ui.el')
-rw-r--r-- | lisp/progmodes/gdb-ui.el | 138 |
1 files changed, 74 insertions, 64 deletions
diff --git a/lisp/progmodes/gdb-ui.el b/lisp/progmodes/gdb-ui.el index 0d1a4b05d65..32db8850b66 100644 --- a/lisp/progmodes/gdb-ui.el +++ b/lisp/progmodes/gdb-ui.el @@ -43,12 +43,22 @@ ;; section in the GDB info manual. ;; GDB developers plan to make the annotation interface obsolete. A new -;; interface called GDB/MI (machine interface) has been designed to replace -;; it. Some GDB/MI commands are used in this file through the CLI command -;; 'interpreter mi <mi-command>'. A file called gdb-mi.el is included with -;; GDB (6.2 onwards) that uses GDB/MI as the primary interface to GDB. It is -;; still under development and is part of a process to migrate Emacs from -;; annotations to GDB/MI. +;; interface called GDB/MI (machine interface) has been designed to replace it. +;; Some GDB/MI commands are used in this file through the CLI command +;; 'interpreter mi <mi-command>'. To help with the process of fully migrating +;; Emacs from annotations to GDB/MI, there is an experimental package called +;; gdb-mi in the Emacs Lisp Package Archive ("http://tromey.com/elpa/"). It +;; comprises of modified gud.el and a file called gdb-mi.el which replaces +;; gdb-ui.el. When installed, this overrides the current files and invoking +;; M-x gdb will use GDB/MI directly (starts with "gdb -i=mi"). When deleted +;; ('d' followed by 'x' in Package Menu mode), the files are deleted and old +;; functionality restored. This provides a convenient way to review the +;; current status/contribute to its improvement. For someone who just wants to +;; use GDB, however, the current mode in Emacs 22 is a much better option. +;; There is also a file, also called gdb-mi.el, a version of which is included +;; the GDB distribution. This will probably only work with versions +;; distributed with GDB 6.5 or later. Unlike the version in ELPA it works on +;; top of gdb-ui.el and you can only start it with M-x gdbmi. ;; This mode SHOULD WORK WITH GDB 5.0 or later but you will NEED AT LEAST ;; GDB 6.0 to use watch expressions. It works best with GDB 6.4 or later @@ -69,25 +79,13 @@ ;;; Known Bugs: -;; 1) Strings that are watched don't update in the speedbar when their -;; contents change unless the first character changes. -;; 2) Cannot handle multiple debug sessions. -;; 3) M-x gdb doesn't work with "run" command in .gdbinit, use M-x gdba instead. -;; 4) M-x gdb doesn't work if the corefile is specified in the command in the -;; minibuffer, use M-x gdba instead (or specify the core in the GUD buffer). -;; 5) If you wish to call procedures from your program in GDB +;; 1) Cannot handle multiple debug sessions. +;; 2) If you wish to call procedures from your program in GDB ;; e.g "call myproc ()", "p mysquare (5)" then use level 2 annotations ;; "gdb --annotate=2 myprog" to keep source buffer/selected frame fixed. -;; 6) After detaching from a process, clicking on the "GO" icon on toolbar +;; 3) After detaching from a process, clicking on the "GO" icon on toolbar ;; (gud-go) sends "continue" to GDB (should be "run"). -;;; Problems with watch expressions, GDB/MI: - -;; 1) They go out of scope when the inferior is re-run. -;; 2) -stack-list-locals has a type field but also prints type in values field. -;; 3) VARNUM increments even when variable object is not created -;; (maybe trivial). - ;;; TODO: ;; 1) Use MI command -data-read-memory for memory window. @@ -138,6 +136,7 @@ Emacs can't find.") (defvar gdb-frame-begin nil "Non-nil when GDB generates frame-begin annotation.") (defvar gdb-printing t) +(defvar gdb-parent-bptno-enabled nil) (defvar gdb-buffer-type nil "One of the symbols bound in `gdb-buffer-rules'.") @@ -222,7 +221,6 @@ handlers.") The directory containing FILE becomes the initial working directory and source-file directory for your debugger. - If `gdb-many-windows' is nil (the default value) then gdb just pops up the GUD buffer unless `gdb-show-main' is t. In this case it starts with two windows: one displaying the GUD buffer and the @@ -1860,7 +1858,7 @@ static char *magick[] = { :group 'gud) (defconst gdb-breakpoint-regexp - "\\([0-9]+\\).*?\\(?:point\\|catch\\s-+\\S-+\\)\\s-+\\S-+\\s-+\\(.\\)\\s-+") + "\\(?:\\([0-9]+\\).*?\\(?:point\\|catch\\s-+\\S-+\\)\\s-+\\S-+\\|\\([0-9]+\\.[0-9]+\\)\\)\\s-+\\(.\\)\\s-+") ;; Put breakpoint icons in relevant margins (even those set in the GUD buffer). (defun gdb-info-breakpoints-custom () @@ -1879,10 +1877,12 @@ static char *magick[] = { (forward-line 1) (if (looking-at gdb-breakpoint-regexp) (progn - (setq bptno (match-string 1)) - (setq flag (char-after (match-beginning 2))) + (setq bptno (or (match-string 1) (match-string 2))) + (setq flag (char-after (match-beginning 3))) + (if (match-string 1) + (setq gdb-parent-bptno-enabled (eq flag ?y))) (add-text-properties - (match-beginning 2) (match-end 2) + (match-beginning 3) (match-end 3) (if (eq flag ?y) '(face font-lock-warning-face) '(face font-lock-type-face))) @@ -1938,6 +1938,9 @@ static char *magick[] = { (end-of-line)))))) (if (gdb-get-buffer 'gdb-assembler-buffer) (gdb-assembler-custom))) +(declare-function gud-remove "gdb-ui" t t) ; gud-def +(declare-function gud-break "gdb-ui" t t) ; gud-def + (defun gdb-mouse-set-clear-breakpoint (event) "Set/clear breakpoint in left fringe/margin with mouse click." (interactive "e") @@ -1963,17 +1966,18 @@ static char *magick[] = { (save-excursion (goto-char (posn-point posn)) (if (posn-object posn) - (gdb-enqueue-input - (list - (let ((bptno (get-text-property - 0 'gdb-bptno (car (posn-string posn))))) + (let* ((bptno (get-text-property + 0 'gdb-bptno (car (posn-string posn))))) + (string-match "\\([0-9+]\\)*" bptno) + (gdb-enqueue-input + (list (concat gdb-server-prefix (if (get-text-property 0 'gdb-enabled (car (posn-string posn))) "disable " "enable ") - bptno "\n")) - 'ignore)))))))) + (match-string 1 bptno) "\n") + 'ignore))))))))) (defun gdb-mouse-toggle-breakpoint-fringe (event) "Enable/disable breakpoint in left fringe with mouse click." @@ -1991,14 +1995,16 @@ static char *magick[] = { (when (overlay-get overlay 'put-break) (setq obj (overlay-get overlay 'before-string)))) (when (stringp obj) - (gdb-enqueue-input - (list - (concat gdb-server-prefix - (if (get-text-property 0 'gdb-enabled obj) - "disable " - "enable ") - (get-text-property 0 'gdb-bptno obj) "\n") - 'ignore)))))))) + (let* ((bptno (get-text-property 0 'gdb-bptno obj))) + (string-match "\\([0-9+]\\)*" bptno) + (gdb-enqueue-input + (list + (concat gdb-server-prefix + (if (get-text-property 0 'gdb-enabled obj) + "disable " + "enable ") + (match-string 1 bptno) "\n") + 'ignore))))))))) (defun gdb-breakpoints-buffer-name () (with-current-buffer gud-comint-buffer @@ -2064,21 +2070,25 @@ static char *magick[] = { (gdb-enqueue-input (list (concat gdb-server-prefix - (if (eq ?y (char-after (match-beginning 2))) + (if (eq ?y (char-after (match-beginning 3))) "disable " "enable ") - (match-string 1) "\n") 'ignore)) + (or (match-string 1) (match-string 2)) "\n") 'ignore)) (error "Not recognized as break/watchpoint line")))) (defun gdb-delete-breakpoint () "Delete the breakpoint at current line." (interactive) - (beginning-of-line 1) - (if (looking-at gdb-breakpoint-regexp) - (gdb-enqueue-input - (list - (concat gdb-server-prefix "delete " (match-string 1) "\n") 'ignore)) - (error "Not recognized as break/watchpoint line"))) + (save-excursion + (beginning-of-line 1) + (if (looking-at gdb-breakpoint-regexp) + (if (match-string 1) + (gdb-enqueue-input + (list + (concat gdb-server-prefix "delete " (match-string 1) "\n") + 'ignore)) + (message-box "This breakpoint cannot be deleted on its own.")) + (error "Not recognized as break/watchpoint line")))) (defun gdb-goto-breakpoint (&optional event) "Display the breakpoint location specified at current line." @@ -2086,7 +2096,7 @@ static char *magick[] = { (if event (posn-set-point (event-end event))) (save-excursion (beginning-of-line 1) - (if (looking-at "\\([0-9]+\\) .+ in .+ at\\s-+\\(\\S-+\\):\\([0-9]+\\)") + (if (looking-at "\\([0-9]+\\.?[0-9]*\\) .+ in .+ at\\s-+\\(\\S-+\\):\\([0-9]+\\)") (let ((bptno (match-string 1)) (file (match-string 2)) (line (match-string 3))) @@ -3156,6 +3166,8 @@ BUFFER nil or omitted means use the current buffer." (delete-overlay overlay)))) (defun gdb-put-breakpoint-icon (enabled bptno) + (if (string-match "[0-9+]+\\." bptno) + (setq enabled gdb-parent-bptno-enabled)) (let ((start (- (line-beginning-position) 1)) (end (+ (line-end-position) 1)) (putstring (if enabled "B" "b")) @@ -3215,8 +3227,8 @@ BUFFER nil or omitted means use the current buffer." (setq left-margin-width 2) (let ((window (get-buffer-window (current-buffer) 0))) (if window - (set-window-margins - window left-margin-width right-margin-width))))) + (set-window-margins + window left-margin-width right-margin-width))))) (gdb-put-string (propertize putstring 'face (if enabled 'breakpoint-enabled 'breakpoint-disabled)) @@ -3286,18 +3298,16 @@ BUFFER nil or omitted means use the current buffer." (goto-char (point-min)) (while (< (point) (- (point-max) 1)) (forward-line 1) - (if (looking-at "[^\t].*?breakpoint") - (progn - (looking-at - "\\([0-9]+\\)\\s-+\\S-+\\s-+\\S-+\\s-+\\(.\\)\\s-+0x0*\\(\\S-+\\)") - (setq bptno (match-string 1)) - (setq flag (char-after (match-beginning 2))) - (setq address (match-string 3)) - (with-current-buffer buffer - (save-excursion - (goto-char (point-min)) - (if (search-forward address nil t) - (gdb-put-breakpoint-icon (eq flag ?y) bptno)))))))) + (when (looking-at + "\\([0-9]+\\.?[0-9]*\\).*?\\s-+\\(.\\)\\s-+0x0*\\(\\S-+\\)") + (setq bptno (match-string 1)) + (setq flag (char-after (match-beginning 2))) + (setq address (match-string 3)) + (with-current-buffer buffer + (save-excursion + (goto-char (point-min)) + (if (search-forward address nil t) + (gdb-put-breakpoint-icon (eq flag ?y) bptno))))))) (if (not (equal gdb-pc-address "main")) (with-current-buffer buffer (set-window-point (get-buffer-window buffer 0) pos))))) @@ -3458,7 +3468,7 @@ is set in them." (gdb-force-mode-line-update (propertize "ready" 'face font-lock-variable-name-face))) -; Uses "-var-list-children --all-values". Needs GDB 6.1 onwards. +; Uses "-var-list-children --all-values". Needs GDB 6.4 onwards. (defun gdb-var-list-children-1 (varnum) (gdb-enqueue-input (list |