diff options
| author | Dmitry Dzhus | 2009-08-04 12:46:26 +0000 |
|---|---|---|
| committer | Dmitry Dzhus | 2009-08-04 12:46:26 +0000 |
| commit | 98bf84941396371b005d52fa2043660a202e3e9e (patch) | |
| tree | 47150bcbc97ac960eb5859fcb8e81ba5d9e08089 | |
| parent | 2ac338048ec036f7eb15d3cb2b29be3faf476c43 (diff) | |
| download | emacs-98bf84941396371b005d52fa2043660a202e3e9e.tar.gz emacs-98bf84941396371b005d52fa2043660a202e3e9e.zip | |
(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.
| -rw-r--r-- | lisp/ChangeLog | 13 | ||||
| -rw-r--r-- | lisp/progmodes/gdb-mi.el | 69 |
2 files changed, 72 insertions, 10 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 2d55c0bb457..cb2aa1bce96 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,16 @@ | |||
| 1 | 2009-08-04 Dmitry Dzhus <dima@sphinx.net.ru> | ||
| 2 | |||
| 3 | * progmodes/gdb-mi.el Basic thread selection support. | ||
| 4 | (gdb-thread-number): New variable. | ||
| 5 | (gdb-current-context-command): New macro which adds --thread | ||
| 6 | option to command. | ||
| 7 | (gdb-threads-mode-map): Select thread with SPC | ||
| 8 | (gdb-thread-list-handler-custom): Mark current thread with overlay | ||
| 9 | arrow. Synchronize GDB thread and Emacs thread. | ||
| 10 | (gdb-select-thread): New command which selects current thread. | ||
| 11 | (gdb-invalidate-frames, gdb-invalidate-locals) | ||
| 12 | (gdb-invalidate-registers): Use --thread option. | ||
| 13 | |||
| 1 | 2009-08-04 Michael Albinus <michael.albinus@gmx.de> | 14 | 2009-08-04 Michael Albinus <michael.albinus@gmx.de> |
| 2 | 15 | ||
| 3 | * net/tramp.el (top): Make check for tramp-gvfs loading more | 16 | * net/tramp.el (top): Make check for tramp-gvfs loading more |
diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el index eb06a387258..5b03ac28956 100644 --- a/lisp/progmodes/gdb-mi.el +++ b/lisp/progmodes/gdb-mi.el | |||
| @@ -117,10 +117,20 @@ Set to \"main\" at start if `gdb-show-main' is t.") | |||
| 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. |
| @@ -1191,6 +1201,12 @@ static char *magick[] = { | |||
| 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" |
| @@ -1210,12 +1226,14 @@ static char *magick[] = { | |||
| 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) |
| @@ -1887,8 +1905,9 @@ FILE is a full path." | |||
| 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 |
| @@ -1908,6 +1927,8 @@ FILE is a full path." | |||
| 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)) |
| @@ -1916,7 +1937,14 @@ FILE is a full path." | |||
| 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) |
| @@ -1929,7 +1957,28 @@ FILE is a full path." | |||
| 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 |
| @@ -2517,7 +2566,7 @@ breakpoints buffer." | |||
| 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 | ||
| @@ -2631,7 +2680,7 @@ member." | |||
| 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 |
| @@ -2759,7 +2808,7 @@ member." | |||
| 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 |
| @@ -2893,7 +2942,7 @@ is set in them." | |||
| 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 | ||