comparison lisp/progmodes/gdb-mi.el @ 104145:ff7110a449a4

(gdb-thread-number): New variable. (gdb-current-context-command): New macro which adds --thread option to command. (gdb-threads-mode-map): Select thread with SPC (gdb-thread-list-handler-custom): Mark current thread with overlay arrow. Synchronize GDB thread and Emacs thread. (gdb-select-thread): New command which selects current thread. (gdb-invalidate-frames, gdb-invalidate-locals) (gdb-invalidate-registers): Use --thread option.
author Dmitry Dzhus <dima@sphinx.net.ru>
date Tue, 04 Aug 2009 12:46:26 +0000
parents 335df621bc5c
children 907e635649e5
comparison
equal deleted inserted replaced
104144:f60678899ee6 104145:ff7110a449a4
115 (defvar gdb-memory-next-page nil 115 (defvar gdb-memory-next-page nil
116 "Address of next memory page for program memory buffer.") 116 "Address of next memory page for program memory buffer.")
117 (defvar gdb-memory-prev-page nil 117 (defvar gdb-memory-prev-page nil
118 "Address of previous memory page for program memory buffer.") 118 "Address of previous memory page for program memory buffer.")
119 119
120 (defvar gdb-frame-number "0")
121 (defvar gdb-thread-number "1"
122 "Main current thread.
123
124 Invalidation triggers use this variable to query GDB for
125 information on the specified thread.
126
127 This variable may be updated implicitly by GDB via
128 `gdb-thread-list-handler-custom' or explicitly by
129 `gdb-select-thread'.")
130
120 (defvar gdb-selected-frame nil) 131 (defvar gdb-selected-frame nil)
121 (defvar gdb-selected-file nil) 132 (defvar gdb-selected-file nil)
122 (defvar gdb-selected-line nil) 133 (defvar gdb-selected-line nil)
123 (defvar gdb-frame-number nil)
124 (defvar gdb-current-language nil) 134 (defvar gdb-current-language nil)
125 (defvar gdb-var-list nil 135 (defvar gdb-var-list nil
126 "List of variables in watch window. 136 "List of variables in watch window.
127 Each element has the form (VARNUM EXPRESSION NUMCHILD TYPE VALUE STATUS) where 137 Each element has the form (VARNUM EXPRESSION NUMCHILD TYPE VALUE STATUS) where
128 STATUS is nil (unchanged), `changed' or `out-of-scope'.") 138 STATUS is nil (unchanged), `changed' or `out-of-scope'.")
1189 (setq gdb-token-number (1+ gdb-token-number)) 1199 (setq gdb-token-number (1+ gdb-token-number))
1190 (setcar item (concat (number-to-string gdb-token-number) (car item))) 1200 (setcar item (concat (number-to-string gdb-token-number) (car item)))
1191 (push (cons gdb-token-number (car (cdr item))) gdb-handler-alist) 1201 (push (cons gdb-token-number (car (cdr item))) gdb-handler-alist)
1192 (process-send-string (get-buffer-process gud-comint-buffer) 1202 (process-send-string (get-buffer-process gud-comint-buffer)
1193 (concat (car item) "\n"))) 1203 (concat (car item) "\n")))
1204
1205 (defmacro gdb-current-context-command (command)
1206 "Add --thread option to gdb COMMAND.
1207
1208 Option value is taken from `gdb-thread-number'."
1209 (concat command " --thread " gdb-thread-number))
1194 1210
1195 1211
1196 (defcustom gud-gdb-command-name "gdb -i=mi" 1212 (defcustom gud-gdb-command-name "gdb -i=mi"
1197 "Default command to execute an executable under the GDB debugger." 1213 "Default command to execute an executable under the GDB debugger."
1198 :type 'string 1214 :type 'string
1208 (when gdb-first-prompt 1224 (when gdb-first-prompt
1209 (gdb-force-mode-line-update 1225 (gdb-force-mode-line-update
1210 (propertize "initializing..." 'face font-lock-variable-name-face)) 1226 (propertize "initializing..." 'face font-lock-variable-name-face))
1211 (gdb-init-1) 1227 (gdb-init-1)
1212 (setq gdb-first-prompt nil)) 1228 (setq gdb-first-prompt nil))
1229 ;; We may need to update gdb-thread-number, so we call threads buffer
1230 (gdb-get-buffer-create 'gdb-threads-buffer)
1231 (gdb-invalidate-threads)
1213 (gdb-get-selected-frame) 1232 (gdb-get-selected-frame)
1214 (gdb-invalidate-frames) 1233 (gdb-invalidate-frames)
1215 ;; Regenerate breakpoints buffer in case it has been inadvertantly deleted. 1234 ;; Regenerate breakpoints buffer in case it has been inadvertantly deleted.
1216 (gdb-get-buffer-create 'gdb-breakpoints-buffer) 1235 (gdb-get-buffer-create 'gdb-breakpoints-buffer)
1217 (gdb-invalidate-breakpoints) 1236 (gdb-invalidate-breakpoints)
1218 (gdb-invalidate-threads)
1219 (gdb-get-changed-registers) 1237 (gdb-get-changed-registers)
1220 (gdb-invalidate-registers) 1238 (gdb-invalidate-registers)
1221 (gdb-invalidate-locals) 1239 (gdb-invalidate-locals)
1222 (gdb-invalidate-memory) 1240 (gdb-invalidate-memory)
1223 (when (and (boundp 'speedbar-frame) (frame-live-p speedbar-frame)) 1241 (when (and (boundp 'speedbar-frame) (frame-live-p speedbar-frame))
1885 (" \\(stopped\\) in " (1 font-lock-warning-face)) 1903 (" \\(stopped\\) in " (1 font-lock-warning-face))
1886 ("\\(\\(\\sw\\|[_.]\\)+\\)=" (1 font-lock-variable-name-face))) 1904 ("\\(\\(\\sw\\|[_.]\\)+\\)=" (1 font-lock-variable-name-face)))
1887 "Font lock keywords used in `gdb-threads-mode'.") 1905 "Font lock keywords used in `gdb-threads-mode'.")
1888 1906
1889 (defvar gdb-threads-mode-map 1907 (defvar gdb-threads-mode-map
1890 ;; TODO 1908 (let ((map (make-sparse-keymap)))
1891 (make-sparse-keymap)) 1909 (define-key map " " 'gdb-select-thread)
1910 map))
1892 1911
1893 (defvar gdb-breakpoints-header 1912 (defvar gdb-breakpoints-header
1894 (list 1913 (list
1895 (gdb-propertize-header "Breakpoints" gdb-breakpoints-buffer 1914 (gdb-propertize-header "Breakpoints" gdb-breakpoints-buffer
1896 nil nil mode-line) 1915 nil nil mode-line)
1906 (setq major-mode 'gdb-threads-mode) 1925 (setq major-mode 'gdb-threads-mode)
1907 (setq mode-name "Threads") 1926 (setq mode-name "Threads")
1908 (use-local-map gdb-threads-mode-map) 1927 (use-local-map gdb-threads-mode-map)
1909 (setq buffer-read-only t) 1928 (setq buffer-read-only t)
1910 (buffer-disable-undo) 1929 (buffer-disable-undo)
1930 (setq gdb-thread-position (make-marker))
1931 (add-to-list 'overlay-arrow-variable-list 'gdb-thread-position)
1911 (setq header-line-format gdb-breakpoints-header) 1932 (setq header-line-format gdb-breakpoints-header)
1912 (set (make-local-variable 'font-lock-defaults) 1933 (set (make-local-variable 'font-lock-defaults)
1913 '(gdb-threads-font-lock-keywords)) 1934 '(gdb-threads-font-lock-keywords))
1914 (run-mode-hooks 'gdb-threads-mode-hook) 1935 (run-mode-hooks 'gdb-threads-mode-hook)
1915 'gdb-invalidate-threads) 1936 'gdb-invalidate-threads)
1916 1937
1917 (defun gdb-thread-list-handler-custom () 1938 (defun gdb-thread-list-handler-custom ()
1918 (let* ((res (json-partial-output)) 1939 (let* ((res (json-partial-output))
1919 (threads-list (gdb-get-field res 'threads))) 1940 (threads-list (gdb-get-field res 'threads))
1941 (current-thread (gdb-get-field res 'current-thread-id)))
1942 (when (and current-thread
1943 (not (string-equal current-thread gdb-thread-number)))
1944 ;; Implicitly switch thread (in case previous one dies)
1945 (message (concat "GDB switched to another thread: " current-thread))
1946 (setq gdb-thread-number current-thread))
1947 (set-marker gdb-thread-position nil)
1920 (dolist (thread threads-list) 1948 (dolist (thread threads-list)
1921 (insert (apply 'format `("%s (%s) %s in %s " 1949 (insert (apply 'format `("%s (%s) %s in %s "
1922 ,@(gdb-get-many-fields thread 'id 'target-id 'state) 1950 ,@(gdb-get-many-fields thread 'id 'target-id 'state)
1923 ,(gdb-get-field thread 'frame 'func)))) 1951 ,(gdb-get-field thread 'frame 'func))))
1924 ;; Arguments 1952 ;; Arguments
1927 (dolist (arg args) 1955 (dolist (arg args)
1928 (insert (apply 'format `("%s=%s" ,@(gdb-get-many-fields arg 'name 'value))))) 1956 (insert (apply 'format `("%s=%s" ,@(gdb-get-many-fields arg 'name 'value)))))
1929 (when args (kill-backward-chars 1))) 1957 (when args (kill-backward-chars 1)))
1930 (insert ")") 1958 (insert ")")
1931 (gdb-insert-frame-location (gdb-get-field thread 'frame)) 1959 (gdb-insert-frame-location (gdb-get-field thread 'frame))
1932 (insert (format " at %s\n" (gdb-get-field thread 'frame 'addr)))))) 1960 (insert (format " at %s" (gdb-get-field thread 'frame 'addr)))
1961 (add-text-properties (line-beginning-position)
1962 (line-end-position)
1963 `(gdb-thread ,thread))
1964 (when (string-equal gdb-thread-number
1965 (gdb-get-field thread 'id))
1966 (set-marker gdb-thread-position (line-beginning-position)))
1967 (newline))))
1968
1969 (defun gdb-select-thread ()
1970 "Select the thread at current line of threads buffer."
1971 (interactive)
1972 (save-excursion
1973 (beginning-of-line)
1974 (let ((thread (get-text-property (point) 'gdb-thread)))
1975 (if thread
1976 (if (string-equal (gdb-get-field thread 'state) "running")
1977 (error "Cannot select running thread")
1978 (let ((new-id (gdb-get-field thread 'id)))
1979 (setq gdb-thread-number new-id)
1980 (gud-basic-call (concat "-thread-select " new-id))))
1981 (error "Not recognized as thread line")))))
1933 1982
1934 1983
1935 ;;; Memory view 1984 ;;; Memory view
1936 1985
1937 (defcustom gdb-memory-rows 8 1986 (defcustom gdb-memory-rows 8
2515 'gdb-stack-buffer-name 2564 'gdb-stack-buffer-name
2516 'gdb-frames-mode) 2565 'gdb-frames-mode)
2517 2566
2518 (def-gdb-auto-updated-buffer gdb-stack-buffer 2567 (def-gdb-auto-updated-buffer gdb-stack-buffer
2519 gdb-invalidate-frames 2568 gdb-invalidate-frames
2520 "-stack-list-frames" 2569 (gdb-current-context-command "-stack-list-frames")
2521 gdb-stack-list-frames-handler 2570 gdb-stack-list-frames-handler
2522 gdb-stack-list-frames-custom) 2571 gdb-stack-list-frames-custom)
2523 2572
2524 (defun gdb-insert-frame-location (frame) 2573 (defun gdb-insert-frame-location (frame)
2525 "Insert \"of file:line\" button or library name for structure FRAME. 2574 "Insert \"of file:line\" button or library name for structure FRAME.
2629 'gdb-locals-buffer-name 2678 'gdb-locals-buffer-name
2630 'gdb-locals-mode) 2679 'gdb-locals-mode)
2631 2680
2632 (def-gdb-auto-update-trigger gdb-invalidate-locals 2681 (def-gdb-auto-update-trigger gdb-invalidate-locals
2633 (gdb-get-buffer 'gdb-locals-buffer) 2682 (gdb-get-buffer 'gdb-locals-buffer)
2634 "-stack-list-locals --simple-values" 2683 (concat (gdb-current-context-command "-stack-list-locals") " --simple-values")
2635 gdb-stack-list-locals-handler) 2684 gdb-stack-list-locals-handler)
2636 2685
2637 (defconst gdb-stack-list-locals-regexp 2686 (defconst gdb-stack-list-locals-regexp
2638 (concat "name=\"\\(.*?\\)\",type=\"\\(.*?\\)\"")) 2687 (concat "name=\"\\(.*?\\)\",type=\"\\(.*?\\)\""))
2639 2688
2757 'gdb-registers-buffer-name 2806 'gdb-registers-buffer-name
2758 'gdb-registers-mode) 2807 'gdb-registers-mode)
2759 2808
2760 (def-gdb-auto-update-trigger gdb-invalidate-registers 2809 (def-gdb-auto-update-trigger gdb-invalidate-registers
2761 (gdb-get-buffer 'gdb-registers-buffer) 2810 (gdb-get-buffer 'gdb-registers-buffer)
2762 "-data-list-register-values x" 2811 (concat (gdb-current-context-command "-data-list-register-values") " x")
2763 gdb-data-list-register-values-handler) 2812 gdb-data-list-register-values-handler)
2764 2813
2765 (defconst gdb-data-list-register-values-regexp 2814 (defconst gdb-data-list-register-values-regexp
2766 "number=\"\\(.*?\\)\",value=\"\\(.*?\\)\"") 2815 "number=\"\\(.*?\\)\",value=\"\\(.*?\\)\"")
2767 2816
2891 2940
2892 (defun gdb-get-selected-frame () 2941 (defun gdb-get-selected-frame ()
2893 (if (not (member 'gdb-get-selected-frame gdb-pending-triggers)) 2942 (if (not (member 'gdb-get-selected-frame gdb-pending-triggers))
2894 (progn 2943 (progn
2895 (gdb-input 2944 (gdb-input
2896 (list "-stack-info-frame" 'gdb-frame-handler)) 2945 (list (gdb-current-context-command "-stack-info-frame") 'gdb-frame-handler))
2897 (push 'gdb-get-selected-frame 2946 (push 'gdb-get-selected-frame
2898 gdb-pending-triggers)))) 2947 gdb-pending-triggers))))
2899 2948
2900 (defun gdb-frame-handler () 2949 (defun gdb-frame-handler ()
2901 (setq gdb-pending-triggers 2950 (setq gdb-pending-triggers