comparison lisp/progmodes/gdb-ui.el @ 91204:53108e6cea98

Merge from emacs--devo--0 Revision: emacs@sv.gnu.org/emacs--unicode--0--patch-294
author Miles Bader <miles@gnu.org>
date Thu, 06 Dec 2007 09:51:45 +0000
parents 880960b70474 f43509daf0ee
children 606f2d163a64
comparison
equal deleted inserted replaced
91203:db40129142b2 91204:53108e6cea98
41 ;; You don't need to know about annotations to use this mode as a debugger, 41 ;; You don't need to know about annotations to use this mode as a debugger,
42 ;; but if you are interested developing the mode itself, see the Annotations 42 ;; but if you are interested developing the mode itself, see the Annotations
43 ;; section in the GDB info manual. 43 ;; section in the GDB info manual.
44 44
45 ;; GDB developers plan to make the annotation interface obsolete. A new 45 ;; GDB developers plan to make the annotation interface obsolete. A new
46 ;; interface called GDB/MI (machine interface) has been designed to replace 46 ;; interface called GDB/MI (machine interface) has been designed to replace it.
47 ;; it. Some GDB/MI commands are used in this file through the CLI command 47 ;; Some GDB/MI commands are used in this file through the CLI command
48 ;; 'interpreter mi <mi-command>'. A file called gdb-mi.el is included with 48 ;; 'interpreter mi <mi-command>'. To help with the process of fully migrating
49 ;; GDB (6.2 onwards) that uses GDB/MI as the primary interface to GDB. It is 49 ;; Emacs from annotations to GDB/MI, there is an experimental package called
50 ;; still under development and is part of a process to migrate Emacs from 50 ;; gdb-mi in the Emacs Lisp Package Archive ("http://tromey.com/elpa/"). It
51 ;; annotations to GDB/MI. 51 ;; comprises of modified gud.el and a file called gdb-mi.el which replaces
52 ;; gdb-ui.el. When installed, this overrides the current files and invoking
53 ;; M-x gdb will use GDB/MI directly (starts with "gdb -i=mi"). When deleted
54 ;; ('d' followed by 'x' in Package Menu mode), the files are deleted and old
55 ;; functionality restored. This provides a convenient way to review the
56 ;; current status/contribute to its improvement. For someone who just wants to
57 ;; use GDB, however, the current mode in Emacs 22 is a much better option.
58 ;; There is also a file, also called gdb-mi.el, a version of which is included
59 ;; the GDB distribution. This will probably only work with versions
60 ;; distributed with GDB 6.5 or later. Unlike the version in ELPA it works on
61 ;; top of gdb-ui.el and you can only start it with M-x gdbmi.
52 62
53 ;; This mode SHOULD WORK WITH GDB 5.0 or later but you will NEED AT LEAST 63 ;; This mode SHOULD WORK WITH GDB 5.0 or later but you will NEED AT LEAST
54 ;; GDB 6.0 to use watch expressions. It works best with GDB 6.4 or later 64 ;; GDB 6.0 to use watch expressions. It works best with GDB 6.4 or later
55 ;; where watch expressions will update more quickly. 65 ;; where watch expressions will update more quickly.
56 66
67 77
68 ;; and compiling with -DUNBUFFERED while debugging. 78 ;; and compiling with -DUNBUFFERED while debugging.
69 79
70 ;;; Known Bugs: 80 ;;; Known Bugs:
71 81
72 ;; 1) Strings that are watched don't update in the speedbar when their 82 ;; 1) Cannot handle multiple debug sessions.
73 ;; contents change unless the first character changes. 83 ;; 2) If you wish to call procedures from your program in GDB
74 ;; 2) Cannot handle multiple debug sessions.
75 ;; 3) M-x gdb doesn't work with "run" command in .gdbinit, use M-x gdba instead.
76 ;; 4) M-x gdb doesn't work if the corefile is specified in the command in the
77 ;; minibuffer, use M-x gdba instead (or specify the core in the GUD buffer).
78 ;; 5) If you wish to call procedures from your program in GDB
79 ;; e.g "call myproc ()", "p mysquare (5)" then use level 2 annotations 84 ;; e.g "call myproc ()", "p mysquare (5)" then use level 2 annotations
80 ;; "gdb --annotate=2 myprog" to keep source buffer/selected frame fixed. 85 ;; "gdb --annotate=2 myprog" to keep source buffer/selected frame fixed.
81 ;; 6) After detaching from a process, clicking on the "GO" icon on toolbar 86 ;; 3) After detaching from a process, clicking on the "GO" icon on toolbar
82 ;; (gud-go) sends "continue" to GDB (should be "run"). 87 ;; (gud-go) sends "continue" to GDB (should be "run").
83
84 ;;; Problems with watch expressions, GDB/MI:
85
86 ;; 1) They go out of scope when the inferior is re-run.
87 ;; 2) -stack-list-locals has a type field but also prints type in values field.
88 ;; 3) VARNUM increments even when variable object is not created
89 ;; (maybe trivial).
90 88
91 ;;; TODO: 89 ;;; TODO:
92 90
93 ;; 1) Use MI command -data-read-memory for memory window. 91 ;; 1) Use MI command -data-read-memory for memory window.
94 ;; 2) Use tree-widget.el instead of the speedbar for watch-expressions? 92 ;; 2) Use tree-widget.el instead of the speedbar for watch-expressions?
136 (defvar gdb-continuation nil) 134 (defvar gdb-continuation nil)
137 (defvar gdb-look-up-stack nil) 135 (defvar gdb-look-up-stack nil)
138 (defvar gdb-frame-begin nil 136 (defvar gdb-frame-begin nil
139 "Non-nil when GDB generates frame-begin annotation.") 137 "Non-nil when GDB generates frame-begin annotation.")
140 (defvar gdb-printing t) 138 (defvar gdb-printing t)
139 (defvar gdb-parent-bptno-enabled nil)
141 140
142 (defvar gdb-buffer-type nil 141 (defvar gdb-buffer-type nil
143 "One of the symbols bound in `gdb-buffer-rules'.") 142 "One of the symbols bound in `gdb-buffer-rules'.")
144 (make-variable-buffer-local 'gdb-buffer-type) 143 (make-variable-buffer-local 'gdb-buffer-type)
145 144
219 ;;;###autoload 218 ;;;###autoload
220 (defun gdb (command-line) 219 (defun gdb (command-line)
221 "Run gdb on program FILE in buffer *gud-FILE*. 220 "Run gdb on program FILE in buffer *gud-FILE*.
222 The directory containing FILE becomes the initial working 221 The directory containing FILE becomes the initial working
223 directory and source-file directory for your debugger. 222 directory and source-file directory for your debugger.
224
225 223
226 If `gdb-many-windows' is nil (the default value) then gdb just 224 If `gdb-many-windows' is nil (the default value) then gdb just
227 pops up the GUD buffer unless `gdb-show-main' is t. In this case 225 pops up the GUD buffer unless `gdb-show-main' is t. In this case
228 it starts with two windows: one displaying the GUD buffer and the 226 it starts with two windows: one displaying the GUD buffer and the
229 other with the source file with the main routine of the inferior. 227 other with the source file with the main routine of the inferior.
1858 (t :background "gray")) 1856 (t :background "gray"))
1859 "Face for disabled breakpoint icon in fringe." 1857 "Face for disabled breakpoint icon in fringe."
1860 :group 'gud) 1858 :group 'gud)
1861 1859
1862 (defconst gdb-breakpoint-regexp 1860 (defconst gdb-breakpoint-regexp
1863 "\\([0-9]+\\).*?\\(?:point\\|catch\\s-+\\S-+\\)\\s-+\\S-+\\s-+\\(.\\)\\s-+") 1861 "\\(?:\\([0-9]+\\).*?\\(?:point\\|catch\\s-+\\S-+\\)\\s-+\\S-+\\|\\([0-9]+\\.[0-9]+\\)\\)\\s-+\\(.\\)\\s-+")
1864 1862
1865 ;; Put breakpoint icons in relevant margins (even those set in the GUD buffer). 1863 ;; Put breakpoint icons in relevant margins (even those set in the GUD buffer).
1866 (defun gdb-info-breakpoints-custom () 1864 (defun gdb-info-breakpoints-custom ()
1867 (let ((flag) (bptno)) 1865 (let ((flag) (bptno))
1868 ;; Remove all breakpoint-icons in source buffers but not assembler buffer. 1866 ;; Remove all breakpoint-icons in source buffers but not assembler buffer.
1877 (goto-char (point-min)) 1875 (goto-char (point-min))
1878 (while (< (point) (- (point-max) 1)) 1876 (while (< (point) (- (point-max) 1))
1879 (forward-line 1) 1877 (forward-line 1)
1880 (if (looking-at gdb-breakpoint-regexp) 1878 (if (looking-at gdb-breakpoint-regexp)
1881 (progn 1879 (progn
1882 (setq bptno (match-string 1)) 1880 (setq bptno (or (match-string 1) (match-string 2)))
1883 (setq flag (char-after (match-beginning 2))) 1881 (setq flag (char-after (match-beginning 3)))
1882 (if (match-string 1)
1883 (setq gdb-parent-bptno-enabled (eq flag ?y)))
1884 (add-text-properties 1884 (add-text-properties
1885 (match-beginning 2) (match-end 2) 1885 (match-beginning 3) (match-end 3)
1886 (if (eq flag ?y) 1886 (if (eq flag ?y)
1887 '(face font-lock-warning-face) 1887 '(face font-lock-warning-face)
1888 '(face font-lock-type-face))) 1888 '(face font-lock-type-face)))
1889 (let ((bl (point)) 1889 (let ((bl (point))
1890 (el (line-end-position))) 1890 (el (line-end-position)))
1936 (match-beginning 1) (match-end 1) 1936 (match-beginning 1) (match-end 1)
1937 '(face font-lock-variable-name-face))))))) 1937 '(face font-lock-variable-name-face)))))))
1938 (end-of-line)))))) 1938 (end-of-line))))))
1939 (if (gdb-get-buffer 'gdb-assembler-buffer) (gdb-assembler-custom))) 1939 (if (gdb-get-buffer 'gdb-assembler-buffer) (gdb-assembler-custom)))
1940 1940
1941 (declare-function gud-remove "gdb-ui" t t) ; gud-def
1942 (declare-function gud-break "gdb-ui" t t) ; gud-def
1943
1941 (defun gdb-mouse-set-clear-breakpoint (event) 1944 (defun gdb-mouse-set-clear-breakpoint (event)
1942 "Set/clear breakpoint in left fringe/margin with mouse click." 1945 "Set/clear breakpoint in left fringe/margin with mouse click."
1943 (interactive "e") 1946 (interactive "e")
1944 (mouse-minibuffer-check event) 1947 (mouse-minibuffer-check event)
1945 (let ((posn (event-end event))) 1948 (let ((posn (event-end event)))
1961 (if (numberp (posn-point posn)) 1964 (if (numberp (posn-point posn))
1962 (with-selected-window (posn-window posn) 1965 (with-selected-window (posn-window posn)
1963 (save-excursion 1966 (save-excursion
1964 (goto-char (posn-point posn)) 1967 (goto-char (posn-point posn))
1965 (if (posn-object posn) 1968 (if (posn-object posn)
1966 (gdb-enqueue-input 1969 (let* ((bptno (get-text-property
1967 (list 1970 0 'gdb-bptno (car (posn-string posn)))))
1968 (let ((bptno (get-text-property 1971 (string-match "\\([0-9+]\\)*" bptno)
1969 0 'gdb-bptno (car (posn-string posn))))) 1972 (gdb-enqueue-input
1973 (list
1970 (concat gdb-server-prefix 1974 (concat gdb-server-prefix
1971 (if (get-text-property 1975 (if (get-text-property
1972 0 'gdb-enabled (car (posn-string posn))) 1976 0 'gdb-enabled (car (posn-string posn)))
1973 "disable " 1977 "disable "
1974 "enable ") 1978 "enable ")
1975 bptno "\n")) 1979 (match-string 1 bptno) "\n")
1976 'ignore)))))))) 1980 'ignore)))))))))
1977 1981
1978 (defun gdb-mouse-toggle-breakpoint-fringe (event) 1982 (defun gdb-mouse-toggle-breakpoint-fringe (event)
1979 "Enable/disable breakpoint in left fringe with mouse click." 1983 "Enable/disable breakpoint in left fringe with mouse click."
1980 (interactive "e") 1984 (interactive "e")
1981 (mouse-minibuffer-check event) 1985 (mouse-minibuffer-check event)
1989 (goto-char pos) 1993 (goto-char pos)
1990 (dolist (overlay (overlays-in pos pos)) 1994 (dolist (overlay (overlays-in pos pos))
1991 (when (overlay-get overlay 'put-break) 1995 (when (overlay-get overlay 'put-break)
1992 (setq obj (overlay-get overlay 'before-string)))) 1996 (setq obj (overlay-get overlay 'before-string))))
1993 (when (stringp obj) 1997 (when (stringp obj)
1994 (gdb-enqueue-input 1998 (let* ((bptno (get-text-property 0 'gdb-bptno obj)))
1995 (list 1999 (string-match "\\([0-9+]\\)*" bptno)
1996 (concat gdb-server-prefix 2000 (gdb-enqueue-input
1997 (if (get-text-property 0 'gdb-enabled obj) 2001 (list
1998 "disable " 2002 (concat gdb-server-prefix
1999 "enable ") 2003 (if (get-text-property 0 'gdb-enabled obj)
2000 (get-text-property 0 'gdb-bptno obj) "\n") 2004 "disable "
2001 'ignore)))))))) 2005 "enable ")
2006 (match-string 1 bptno) "\n")
2007 'ignore)))))))))
2002 2008
2003 (defun gdb-breakpoints-buffer-name () 2009 (defun gdb-breakpoints-buffer-name ()
2004 (with-current-buffer gud-comint-buffer 2010 (with-current-buffer gud-comint-buffer
2005 (concat "*breakpoints of " (gdb-get-target-string) "*"))) 2011 (concat "*breakpoints of " (gdb-get-target-string) "*")))
2006 2012
2062 (beginning-of-line 1) 2068 (beginning-of-line 1)
2063 (if (looking-at gdb-breakpoint-regexp) 2069 (if (looking-at gdb-breakpoint-regexp)
2064 (gdb-enqueue-input 2070 (gdb-enqueue-input
2065 (list 2071 (list
2066 (concat gdb-server-prefix 2072 (concat gdb-server-prefix
2067 (if (eq ?y (char-after (match-beginning 2))) 2073 (if (eq ?y (char-after (match-beginning 3)))
2068 "disable " 2074 "disable "
2069 "enable ") 2075 "enable ")
2070 (match-string 1) "\n") 'ignore)) 2076 (or (match-string 1) (match-string 2)) "\n") 'ignore))
2071 (error "Not recognized as break/watchpoint line")))) 2077 (error "Not recognized as break/watchpoint line"))))
2072 2078
2073 (defun gdb-delete-breakpoint () 2079 (defun gdb-delete-breakpoint ()
2074 "Delete the breakpoint at current line." 2080 "Delete the breakpoint at current line."
2075 (interactive) 2081 (interactive)
2076 (beginning-of-line 1) 2082 (save-excursion
2077 (if (looking-at gdb-breakpoint-regexp) 2083 (beginning-of-line 1)
2078 (gdb-enqueue-input 2084 (if (looking-at gdb-breakpoint-regexp)
2079 (list 2085 (if (match-string 1)
2080 (concat gdb-server-prefix "delete " (match-string 1) "\n") 'ignore)) 2086 (gdb-enqueue-input
2081 (error "Not recognized as break/watchpoint line"))) 2087 (list
2088 (concat gdb-server-prefix "delete " (match-string 1) "\n")
2089 'ignore))
2090 (message-box "This breakpoint cannot be deleted on its own."))
2091 (error "Not recognized as break/watchpoint line"))))
2082 2092
2083 (defun gdb-goto-breakpoint (&optional event) 2093 (defun gdb-goto-breakpoint (&optional event)
2084 "Display the breakpoint location specified at current line." 2094 "Display the breakpoint location specified at current line."
2085 (interactive (list last-input-event)) 2095 (interactive (list last-input-event))
2086 (if event (posn-set-point (event-end event))) 2096 (if event (posn-set-point (event-end event)))
2087 (save-excursion 2097 (save-excursion
2088 (beginning-of-line 1) 2098 (beginning-of-line 1)
2089 (if (looking-at "\\([0-9]+\\) .+ in .+ at\\s-+\\(\\S-+\\):\\([0-9]+\\)") 2099 (if (looking-at "\\([0-9]+\\.?[0-9]*\\) .+ in .+ at\\s-+\\(\\S-+\\):\\([0-9]+\\)")
2090 (let ((bptno (match-string 1)) 2100 (let ((bptno (match-string 1))
2091 (file (match-string 2)) 2101 (file (match-string 2))
2092 (line (match-string 3))) 2102 (line (match-string 3)))
2093 (save-selected-window 2103 (save-selected-window
2094 (let* ((buffer (find-file-noselect 2104 (let* ((buffer (find-file-noselect
3154 (dolist (overlay (overlays-in start end)) 3164 (dolist (overlay (overlays-in start end))
3155 (when (overlay-get overlay 'put-break) 3165 (when (overlay-get overlay 'put-break)
3156 (delete-overlay overlay)))) 3166 (delete-overlay overlay))))
3157 3167
3158 (defun gdb-put-breakpoint-icon (enabled bptno) 3168 (defun gdb-put-breakpoint-icon (enabled bptno)
3169 (if (string-match "[0-9+]+\\." bptno)
3170 (setq enabled gdb-parent-bptno-enabled))
3159 (let ((start (- (line-beginning-position) 1)) 3171 (let ((start (- (line-beginning-position) 1))
3160 (end (+ (line-end-position) 1)) 3172 (end (+ (line-end-position) 1))
3161 (putstring (if enabled "B" "b")) 3173 (putstring (if enabled "B" "b"))
3162 (source-window (get-buffer-window (current-buffer) 0))) 3174 (source-window (get-buffer-window (current-buffer) 0)))
3163 (add-text-properties 3175 (add-text-properties
3213 (when (< left-margin-width 2) 3225 (when (< left-margin-width 2)
3214 (save-current-buffer 3226 (save-current-buffer
3215 (setq left-margin-width 2) 3227 (setq left-margin-width 2)
3216 (let ((window (get-buffer-window (current-buffer) 0))) 3228 (let ((window (get-buffer-window (current-buffer) 0)))
3217 (if window 3229 (if window
3218 (set-window-margins 3230 (set-window-margins
3219 window left-margin-width right-margin-width))))) 3231 window left-margin-width right-margin-width)))))
3220 (gdb-put-string 3232 (gdb-put-string
3221 (propertize putstring 3233 (propertize putstring
3222 'face (if enabled 'breakpoint-enabled 'breakpoint-disabled)) 3234 'face (if enabled 'breakpoint-enabled 'breakpoint-disabled))
3223 (1+ start))))) 3235 (1+ start)))))
3224 3236
3284 (gdb-remove-breakpoint-icons (point-min) (point-max)))) 3296 (gdb-remove-breakpoint-icons (point-min) (point-max))))
3285 (with-current-buffer (gdb-get-buffer 'gdb-breakpoints-buffer) 3297 (with-current-buffer (gdb-get-buffer 'gdb-breakpoints-buffer)
3286 (goto-char (point-min)) 3298 (goto-char (point-min))
3287 (while (< (point) (- (point-max) 1)) 3299 (while (< (point) (- (point-max) 1))
3288 (forward-line 1) 3300 (forward-line 1)
3289 (if (looking-at "[^\t].*?breakpoint") 3301 (when (looking-at
3290 (progn 3302 "\\([0-9]+\\.?[0-9]*\\).*?\\s-+\\(.\\)\\s-+0x0*\\(\\S-+\\)")
3291 (looking-at 3303 (setq bptno (match-string 1))
3292 "\\([0-9]+\\)\\s-+\\S-+\\s-+\\S-+\\s-+\\(.\\)\\s-+0x0*\\(\\S-+\\)") 3304 (setq flag (char-after (match-beginning 2)))
3293 (setq bptno (match-string 1)) 3305 (setq address (match-string 3))
3294 (setq flag (char-after (match-beginning 2))) 3306 (with-current-buffer buffer
3295 (setq address (match-string 3)) 3307 (save-excursion
3296 (with-current-buffer buffer 3308 (goto-char (point-min))
3297 (save-excursion 3309 (if (search-forward address nil t)
3298 (goto-char (point-min)) 3310 (gdb-put-breakpoint-icon (eq flag ?y) bptno)))))))
3299 (if (search-forward address nil t)
3300 (gdb-put-breakpoint-icon (eq flag ?y) bptno))))))))
3301 (if (not (equal gdb-pc-address "main")) 3311 (if (not (equal gdb-pc-address "main"))
3302 (with-current-buffer buffer 3312 (with-current-buffer buffer
3303 (set-window-point (get-buffer-window buffer 0) pos))))) 3313 (set-window-point (get-buffer-window buffer 0) pos)))))
3304 3314
3305 (defvar gdb-assembler-mode-map 3315 (defvar gdb-assembler-mode-map
3456 (gdb-create-define-alist) 3466 (gdb-create-define-alist)
3457 (add-hook 'after-save-hook 'gdb-create-define-alist nil t))))) 3467 (add-hook 'after-save-hook 'gdb-create-define-alist nil t)))))
3458 (gdb-force-mode-line-update 3468 (gdb-force-mode-line-update
3459 (propertize "ready" 'face font-lock-variable-name-face))) 3469 (propertize "ready" 'face font-lock-variable-name-face)))
3460 3470
3461 ; Uses "-var-list-children --all-values". Needs GDB 6.1 onwards. 3471 ; Uses "-var-list-children --all-values". Needs GDB 6.4 onwards.
3462 (defun gdb-var-list-children-1 (varnum) 3472 (defun gdb-var-list-children-1 (varnum)
3463 (gdb-enqueue-input 3473 (gdb-enqueue-input
3464 (list 3474 (list
3465 (if (eq (buffer-local-value 'gud-minor-mode gud-comint-buffer) 'gdba) 3475 (if (eq (buffer-local-value 'gud-minor-mode gud-comint-buffer) 'gdba)
3466 (concat "server interpreter mi \"-var-list-children --all-values " 3476 (concat "server interpreter mi \"-var-list-children --all-values "