diff options
| author | Dmitry Dzhus | 2009-08-04 14:19:08 +0000 |
|---|---|---|
| committer | Dmitry Dzhus | 2009-08-04 14:19:08 +0000 |
| commit | 9e919ceebc9dd5f177d37886e10bfcce0de6664b (patch) | |
| tree | a066192379144e7481910eb22d68e7ed2ab40853 | |
| parent | e70866834ebd63f1647a4395cafb1d50ebd927d3 (diff) | |
| download | emacs-9e919ceebc9dd5f177d37886e10bfcce0de6664b.tar.gz emacs-9e919ceebc9dd5f177d37886e10bfcce0de6664b.zip | |
(gdb-pc-address): Removed unused variable.
(gdb-threads-list, gdb-breakpoints-list): New assoc lists.
(gdb-parent-mode): New mode to derive other GDB modes from.
(gdb-display-disassembly-for-thread)
(gdb-frame-disassembly-for-thread): New commands for threads
buffer.
| -rw-r--r-- | lisp/ChangeLog | 6 | ||||
| -rw-r--r-- | lisp/progmodes/gdb-mi.el | 274 |
2 files changed, 166 insertions, 114 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 078d66bbf29..85f277eed8f 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -35,6 +35,12 @@ | |||
| 35 | (gdb-frame-locals-for-thread, gdb-frame-registers-for-thread): New | 35 | (gdb-frame-locals-for-thread, gdb-frame-registers-for-thread): New |
| 36 | commands which show buffers bound to thread. | 36 | commands which show buffers bound to thread. |
| 37 | (gdb-stack-list-locals-regexp): Removed unused regexp. | 37 | (gdb-stack-list-locals-regexp): Removed unused regexp. |
| 38 | (gdb-pc-address): Removed unused variable. | ||
| 39 | (gdb-threads-list, gdb-breakpoints-list): New assoc lists. | ||
| 40 | (gdb-parent-mode): New mode to derive other GDB modes from. | ||
| 41 | (gdb-display-disassembly-for-thread) | ||
| 42 | (gdb-frame-disassembly-for-thread): New commands for threads | ||
| 43 | buffer. | ||
| 38 | 44 | ||
| 39 | 2009-08-04 Michael Albinus <michael.albinus@gmx.de> | 45 | 2009-08-04 Michael Albinus <michael.albinus@gmx.de> |
| 40 | 46 | ||
diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el index f0d5664f74c..a5119e4257e 100644 --- a/lisp/progmodes/gdb-mi.el +++ b/lisp/progmodes/gdb-mi.el | |||
| @@ -107,8 +107,6 @@ | |||
| 107 | (defvar speedbar-initial-expansion-list-name) | 107 | (defvar speedbar-initial-expansion-list-name) |
| 108 | (defvar speedbar-frame) | 108 | (defvar speedbar-frame) |
| 109 | 109 | ||
| 110 | (defvar gdb-pc-address nil "Initialization for Assembler buffer. | ||
| 111 | Set to \"main\" at start if `gdb-show-main' is t.") | ||
| 112 | (defvar gdb-memory-address "main") | 110 | (defvar gdb-memory-address "main") |
| 113 | (defvar gdb-memory-last-address nil | 111 | (defvar gdb-memory-last-address nil |
| 114 | "Last successfully accessed memory address.") | 112 | "Last successfully accessed memory address.") |
| @@ -122,15 +120,38 @@ Set to \"main\" at start if `gdb-show-main' is t.") | |||
| 122 | "Main current thread. | 120 | "Main current thread. |
| 123 | 121 | ||
| 124 | Invalidation triggers use this variable to query GDB for | 122 | Invalidation triggers use this variable to query GDB for |
| 125 | information on the specified thread. | 123 | information on the specified thread by wrapping GDB/MI commands |
| 124 | in `gdb-current-context-command'. | ||
| 126 | 125 | ||
| 127 | This variable may be updated implicitly by GDB via | 126 | This variable may be updated implicitly by GDB via |
| 128 | `gdb-thread-list-handler-custom' or explicitly by | 127 | `gdb-thread-list-handler-custom' or explicitly by |
| 129 | `gdb-select-thread'.") | 128 | `gdb-select-thread'.") |
| 130 | 129 | ||
| 131 | (defvar gdb-selected-frame nil) | 130 | ;; Used to show overlay arrow in source buffer. All set in |
| 132 | (defvar gdb-selected-file nil) | 131 | ;; gdb-get-main-selected-frame. Disassembly buffer should not use |
| 133 | (defvar gdb-selected-line nil) | 132 | ;; these but rely on buffer-local thread information instead. |
| 133 | (defvar gdb-selected-frame nil | ||
| 134 | "Name of selected function for main current thread.") | ||
| 135 | (defvar gdb-selected-file nil | ||
| 136 | "Name of selected file for main current thread.") | ||
| 137 | (defvar gdb-selected-line nil | ||
| 138 | "Number of selected line for main current thread.") | ||
| 139 | |||
| 140 | (defvar gdb-threads-list nil | ||
| 141 | "Associative list of threads provided by \"-thread-info\" MI command. | ||
| 142 | |||
| 143 | Keys are thread numbers (in strings) and values are structures as | ||
| 144 | returned from -thread-info by `json-partial-output'. Updated in | ||
| 145 | `gdb-thread-list-handler-custom'.") | ||
| 146 | |||
| 147 | (defvar gdb-breakpoints-list nil | ||
| 148 | "Associative list of breakpoints provided by \"-break-list\" MI command. | ||
| 149 | |||
| 150 | Keys are breakpoint numbers (in string) and values are structures | ||
| 151 | as returned from \"-break-list\" by `json-partial-output' | ||
| 152 | \(\"body\" field is used). Updated in | ||
| 153 | `gdb-breakpoints-list-handler-custom'.") | ||
| 154 | |||
| 134 | (defvar gdb-current-language nil) | 155 | (defvar gdb-current-language nil) |
| 135 | (defvar gdb-var-list nil | 156 | (defvar gdb-var-list nil |
| 136 | "List of variables in watch window. | 157 | "List of variables in watch window. |
| @@ -139,12 +160,7 @@ STATUS is nil (unchanged), `changed' or `out-of-scope'.") | |||
| 139 | (defvar gdb-main-file nil "Source file from which program execution begins.") | 160 | (defvar gdb-main-file nil "Source file from which program execution begins.") |
| 140 | (defvar gdb-overlay-arrow-position nil) | 161 | (defvar gdb-overlay-arrow-position nil) |
| 141 | (defvar gdb-stack-position nil) | 162 | (defvar gdb-stack-position nil) |
| 142 | (defvar gdb-breakpoints-list nil | ||
| 143 | "List of breakpoints. | ||
| 144 | 163 | ||
| 145 | `gdb-get-field' is used to access breakpoints data stored in this | ||
| 146 | variable. Each element contains the same fields as \"body\" | ||
| 147 | member of \"-break-info\".") | ||
| 148 | (defvar gdb-location-alist nil | 164 | (defvar gdb-location-alist nil |
| 149 | "Alist of breakpoint numbers and full filenames. Only used for files that | 165 | "Alist of breakpoint numbers and full filenames. Only used for files that |
| 150 | Emacs can't find.") | 166 | Emacs can't find.") |
| @@ -474,7 +490,6 @@ detailed description of this mode. | |||
| 474 | 'gdb-mouse-jump) | 490 | 'gdb-mouse-jump) |
| 475 | ;; | 491 | ;; |
| 476 | ;; (re-)initialise | 492 | ;; (re-)initialise |
| 477 | (setq gdb-pc-address (if gdb-show-main "main" nil)) | ||
| 478 | (setq gdb-selected-frame nil | 493 | (setq gdb-selected-frame nil |
| 479 | gdb-frame-number nil | 494 | gdb-frame-number nil |
| 480 | gdb-var-list nil | 495 | gdb-var-list nil |
| @@ -920,19 +935,29 @@ INDENT is the current indentation depth." | |||
| 920 | gdb-buffer-rules)))) | 935 | gdb-buffer-rules)))) |
| 921 | (when f (rename-buffer (funcall f))))) | 936 | (when f (rename-buffer (funcall f))))) |
| 922 | 937 | ||
| 938 | (defun gdb-current-buffer-rules () | ||
| 939 | "Get `gdb-buffer-rules' entry for current buffer type." | ||
| 940 | (assoc gdb-buffer-type gdb-buffer-rules)) | ||
| 941 | |||
| 942 | (defun gdb-current-buffer-thread () | ||
| 943 | "Get thread of current buffer from `gdb-threads-list'." | ||
| 944 | (cdr (assoc gdb-thread-number gdb-threads-list))) | ||
| 945 | |||
| 946 | (defun gdb-current-buffer-frame () | ||
| 947 | "Get current stack frame for thread of current buffer." | ||
| 948 | (gdb-get-field (gdb-current-buffer-thread) 'frame)) | ||
| 949 | |||
| 923 | (defun gdb-get-buffer (key &optional thread) | 950 | (defun gdb-get-buffer (key &optional thread) |
| 924 | "Get a specific GDB buffer. | 951 | "Get a specific GDB buffer. |
| 925 | 952 | ||
| 926 | In that buffer, `gdb-buffer-type' must be equal to KEY and | 953 | In that buffer, `gdb-buffer-type' must be equal to KEY and |
| 927 | `gdb-thread-number' (if provided) must be equal to THREAD. | 954 | `gdb-thread-number' (if provided) must be equal to THREAD." |
| 928 | |||
| 929 | When THREAD is nil, global `gdb-thread-number' value is used." | ||
| 930 | (when (not thread) (setq thread gdb-thread-number)) | ||
| 931 | (catch 'found | 955 | (catch 'found |
| 932 | (dolist (buffer (buffer-list) nil) | 956 | (dolist (buffer (buffer-list) nil) |
| 933 | (with-current-buffer buffer | 957 | (with-current-buffer buffer |
| 934 | (when (and (eq gdb-buffer-type key) | 958 | (when (and (eq gdb-buffer-type key) |
| 935 | (equal gdb-thread-number thread)) | 959 | (or (not thread) |
| 960 | (equal gdb-thread-number thread))) | ||
| 936 | (throw 'found buffer)))))) | 961 | (throw 'found buffer)))))) |
| 937 | 962 | ||
| 938 | (defun gdb-get-buffer-create (key &optional thread) | 963 | (defun gdb-get-buffer-create (key &optional thread) |
| @@ -1012,6 +1037,26 @@ DOC is an optional documentation string." | |||
| 1012 | (push (cons buffer-type rules) | 1037 | (push (cons buffer-type rules) |
| 1013 | gdb-buffer-rules)))) | 1038 | gdb-buffer-rules)))) |
| 1014 | 1039 | ||
| 1040 | (defun gdb-parent-mode () | ||
| 1041 | "Generic mode to derive all other GDB buffer modes from." | ||
| 1042 | (setq buffer-read-only t) | ||
| 1043 | (buffer-disable-undo) | ||
| 1044 | ;; Delete buffer from gdb-buf-publisher when it's killed | ||
| 1045 | ;; (if it has an associated update trigger) | ||
| 1046 | (add-hook | ||
| 1047 | 'kill-buffer-hook | ||
| 1048 | (function | ||
| 1049 | (lambda () | ||
| 1050 | (let ((trigger (gdb-rules-update-trigger | ||
| 1051 | (gdb-get-current-buffer-rules)))) | ||
| 1052 | (when trigger | ||
| 1053 | (gdb-delete-subscriber | ||
| 1054 | gdb-buf-publisher | ||
| 1055 | ;; This should match gdb-add-subscriber done in | ||
| 1056 | ;; gdb-get-buffer-create | ||
| 1057 | (cons (current-buffer) | ||
| 1058 | (gdb-bind-function-to-buffer trigger (current-buffer)))))))))) | ||
| 1059 | |||
| 1015 | ;; GUD buffers are an exception to the rules | 1060 | ;; GUD buffers are an exception to the rules |
| 1016 | (gdb-set-buffer-rules 'gdbmi 'error) | 1061 | (gdb-set-buffer-rules 'gdbmi 'error) |
| 1017 | 1062 | ||
| @@ -1264,7 +1309,12 @@ Option value is taken from `gdb-thread-number'." | |||
| 1264 | 1309 | ||
| 1265 | SUBSCRIBER must be a pair, where cdr is a function of one | 1310 | SUBSCRIBER must be a pair, where cdr is a function of one |
| 1266 | argument (see `gdb-emit-signal')." | 1311 | argument (see `gdb-emit-signal')." |
| 1267 | `(add-to-list ',publisher ,subscriber)) | 1312 | `(add-to-list ',publisher ,subscriber t)) |
| 1313 | |||
| 1314 | (defmacro gdb-delete-subscriber (publisher subscriber) | ||
| 1315 | "Unregister SUBSCRIBER from PUBLISHER." | ||
| 1316 | `(setq ,publisher (delete ,subscriber | ||
| 1317 | ,publisher))) | ||
| 1268 | 1318 | ||
| 1269 | (defun gdb-get-subscribers (publisher) | 1319 | (defun gdb-get-subscribers (publisher) |
| 1270 | publisher) | 1320 | publisher) |
| @@ -1288,13 +1338,15 @@ valid signal handlers.") | |||
| 1288 | (propertize "initializing..." 'face font-lock-variable-name-face)) | 1338 | (propertize "initializing..." 'face font-lock-variable-name-face)) |
| 1289 | (gdb-init-1) | 1339 | (gdb-init-1) |
| 1290 | (setq gdb-first-prompt nil)) | 1340 | (setq gdb-first-prompt nil)) |
| 1291 | ;; We may need to update gdb-thread-number, so we call threads buffer | 1341 | ;; We may need to update gdb-thread-number and gdb-threads-list |
| 1292 | (gdb-get-buffer-create 'gdb-threads-buffer) | 1342 | (gdb-get-buffer-create 'gdb-threads-buffer) |
| 1293 | ;; Regenerate breakpoints buffer in case it has been inadvertantly deleted. | 1343 | ;; gdb-break-list is maintained in breakpoints handler |
| 1294 | (gdb-get-buffer-create 'gdb-breakpoints-buffer) | 1344 | (gdb-get-buffer-create 'gdb-breakpoints-buffer) |
| 1295 | 1345 | ||
| 1346 | (gdb-get-main-selected-frame) | ||
| 1347 | |||
| 1296 | (gdb-emit-signal gdb-buf-publisher 'update) | 1348 | (gdb-emit-signal gdb-buf-publisher 'update) |
| 1297 | (gdb-get-selected-frame) | 1349 | |
| 1298 | (gdb-get-changed-registers) | 1350 | (gdb-get-changed-registers) |
| 1299 | 1351 | ||
| 1300 | (when (and (boundp 'speedbar-frame) (frame-live-p speedbar-frame)) | 1352 | (when (and (boundp 'speedbar-frame) (frame-live-p speedbar-frame)) |
| @@ -1576,14 +1628,22 @@ are not guaranteed." | |||
| 1576 | (dolist (field fields values) | 1628 | (dolist (field fields values) |
| 1577 | (setq values (append values (list (gdb-get-field struct field))))))) | 1629 | (setq values (append values (list (gdb-get-field struct field))))))) |
| 1578 | 1630 | ||
| 1579 | ;; NAME is the function name. | ||
| 1580 | ;; GDB-COMMAND is a string of such. HANDLER-NAME is the function bound to the | ||
| 1581 | ;; current input and buffer which recieved the trigger signal. | ||
| 1582 | ;; Trigger must be bound to buffer via gdb-bind-function-to-buffer before use! | ||
| 1583 | ;; See how it's done in gdb-get-buffer-create. | ||
| 1584 | |||
| 1585 | (defmacro def-gdb-auto-update-trigger (trigger-name gdb-command | 1631 | (defmacro def-gdb-auto-update-trigger (trigger-name gdb-command |
| 1586 | handler-name) | 1632 | handler-name) |
| 1633 | "Define a trigger TRIGGER-NAME which sends GDB-COMMAND and sets | ||
| 1634 | HANDLER-NAME as its handler. HANDLER-NAME is bound to current | ||
| 1635 | buffer with `gdb-bind-function-to-buffer'. | ||
| 1636 | |||
| 1637 | Normally the trigger defined by this command must be called from | ||
| 1638 | the buffer where HANDLER-NAME must work. This should be done so | ||
| 1639 | that buffer-local thread number may be used in GDB-COMMAND (by | ||
| 1640 | calling `gdb-current-context-command'). | ||
| 1641 | `gdb-bind-function-to-buffer' is used to achieve this, see how | ||
| 1642 | it's done in `gdb-get-buffer-create'. | ||
| 1643 | |||
| 1644 | Triggers defined by this command are meant to be used as a | ||
| 1645 | trigger argument when describing buffer types with | ||
| 1646 | `gdb-set-buffer-rules'." | ||
| 1587 | `(defun ,trigger-name (&optional signal) | 1647 | `(defun ,trigger-name (&optional signal) |
| 1588 | (if (not (gdb-pending-p | 1648 | (if (not (gdb-pending-p |
| 1589 | (cons (current-buffer) ',trigger-name))) | 1649 | (cons (current-buffer) ',trigger-name))) |
| @@ -1611,9 +1671,11 @@ erase current buffer and evaluate CUSTOM-DEFUN." | |||
| 1611 | handler-name custom-defun) | 1671 | handler-name custom-defun) |
| 1612 | "Define trigger and handler. | 1672 | "Define trigger and handler. |
| 1613 | 1673 | ||
| 1614 | TRIGGER-NAME trigger is defined to send GDB-COMMAND. | 1674 | TRIGGER-NAME trigger is defined to send GDB-COMMAND. See |
| 1675 | `def-gdb-auto-update-trigger'. | ||
| 1615 | 1676 | ||
| 1616 | HANDLER-NAME handler uses customization of CUSTOM-DEFUN." | 1677 | HANDLER-NAME handler uses customization of CUSTOM-DEFUN. See |
| 1678 | `def-gdb-auto-update-handler'." | ||
| 1617 | `(progn | 1679 | `(progn |
| 1618 | (def-gdb-auto-update-trigger ,trigger-name | 1680 | (def-gdb-auto-update-trigger ,trigger-name |
| 1619 | ,gdb-command | 1681 | ,gdb-command |
| @@ -1638,9 +1700,12 @@ HANDLER-NAME handler uses customization of CUSTOM-DEFUN." | |||
| 1638 | (let ((breakpoints-list (gdb-get-field | 1700 | (let ((breakpoints-list (gdb-get-field |
| 1639 | (json-partial-output "bkpt" "script") | 1701 | (json-partial-output "bkpt" "script") |
| 1640 | 'BreakpointTable 'body))) | 1702 | 'BreakpointTable 'body))) |
| 1641 | (setq gdb-breakpoints-list breakpoints-list) | 1703 | (setq gdb-breakpoints-list nil) |
| 1642 | (insert "Num\tType\t\tDisp\tEnb\tHits\tAddr What\n") | 1704 | (insert "Num\tType\t\tDisp\tEnb\tHits\tAddr What\n") |
| 1643 | (dolist (breakpoint breakpoints-list) | 1705 | (dolist (breakpoint breakpoints-list) |
| 1706 | (add-to-list 'gdb-breakpoints-list | ||
| 1707 | (cons (gdb-get-field breakpoint 'number) | ||
| 1708 | breakpoint)) | ||
| 1644 | (insert | 1709 | (insert |
| 1645 | (concat | 1710 | (concat |
| 1646 | (gdb-get-field breakpoint 'number) "\t" | 1711 | (gdb-get-field breakpoint 'number) "\t" |
| @@ -1682,7 +1747,9 @@ HANDLER-NAME handler uses customization of CUSTOM-DEFUN." | |||
| 1682 | (not (string-match "\\` ?\\*.+\\*\\'" (buffer-name)))) | 1747 | (not (string-match "\\` ?\\*.+\\*\\'" (buffer-name)))) |
| 1683 | (gdb-remove-breakpoint-icons (point-min) (point-max))))) | 1748 | (gdb-remove-breakpoint-icons (point-min) (point-max))))) |
| 1684 | (dolist (breakpoint gdb-breakpoints-list) | 1749 | (dolist (breakpoint gdb-breakpoints-list) |
| 1685 | (let ((line (gdb-get-field breakpoint 'line))) | 1750 | (let* ((breakpoint (cdr breakpoint)) ; gdb-breakpoints-list is |
| 1751 | ; an associative list | ||
| 1752 | (line (gdb-get-field breakpoint 'line))) | ||
| 1686 | (when line | 1753 | (when line |
| 1687 | (let ((file (gdb-get-field breakpoint 'fullname)) | 1754 | (let ((file (gdb-get-field breakpoint 'fullname)) |
| 1688 | (flag (gdb-get-field breakpoint 'enabled)) | 1755 | (flag (gdb-get-field breakpoint 'enabled)) |
| @@ -1966,6 +2033,8 @@ FILE is a full path." | |||
| 1966 | (define-key map "L" 'gdb-frame-locals-for-thread) | 2033 | (define-key map "L" 'gdb-frame-locals-for-thread) |
| 1967 | (define-key map "r" 'gdb-display-registers-for-thread) | 2034 | (define-key map "r" 'gdb-display-registers-for-thread) |
| 1968 | (define-key map "R" 'gdb-frame-registers-for-thread) | 2035 | (define-key map "R" 'gdb-frame-registers-for-thread) |
| 2036 | (define-key map "d" 'gdb-display-disassembly-for-thread) | ||
| 2037 | (define-key map "D" 'gdb-frame-disassembly-for-thread) | ||
| 1969 | map)) | 2038 | map)) |
| 1970 | 2039 | ||
| 1971 | (defvar gdb-breakpoints-header | 2040 | (defvar gdb-breakpoints-header |
| @@ -1975,17 +2044,10 @@ FILE is a full path." | |||
| 1975 | " " | 2044 | " " |
| 1976 | (gdb-propertize-header "Threads" gdb-threads-buffer | 2045 | (gdb-propertize-header "Threads" gdb-threads-buffer |
| 1977 | "mouse-1: select" mode-line-highlight mode-line-inactive))) | 2046 | "mouse-1: select" mode-line-highlight mode-line-inactive))) |
| 1978 | 2047 | (define-derived-mode gdb-threads-mode gdb-parent-mode "Threads" | |
| 1979 | (defun gdb-threads-mode () | ||
| 1980 | "Major mode for GDB threads. | 2048 | "Major mode for GDB threads. |
| 1981 | 2049 | ||
| 1982 | \\{gdb-threads-mode-map}" | 2050 | \\{gdb-threads-mode-map}" |
| 1983 | (kill-all-local-variables) | ||
| 1984 | (setq major-mode 'gdb-threads-mode) | ||
| 1985 | (setq mode-name "Threads") | ||
| 1986 | (use-local-map gdb-threads-mode-map) | ||
| 1987 | (setq buffer-read-only t) | ||
| 1988 | (buffer-disable-undo) | ||
| 1989 | (setq gdb-thread-position (make-marker)) | 2051 | (setq gdb-thread-position (make-marker)) |
| 1990 | (add-to-list 'overlay-arrow-variable-list 'gdb-thread-position) | 2052 | (add-to-list 'overlay-arrow-variable-list 'gdb-thread-position) |
| 1991 | (setq header-line-format gdb-breakpoints-header) | 2053 | (setq header-line-format gdb-breakpoints-header) |
| @@ -1998,6 +2060,7 @@ FILE is a full path." | |||
| 1998 | (let* ((res (json-partial-output)) | 2060 | (let* ((res (json-partial-output)) |
| 1999 | (threads-list (gdb-get-field res 'threads)) | 2061 | (threads-list (gdb-get-field res 'threads)) |
| 2000 | (current-thread (gdb-get-field res 'current-thread-id))) | 2062 | (current-thread (gdb-get-field res 'current-thread-id))) |
| 2063 | (setq gdb-threads-list nil) | ||
| 2001 | (when (and current-thread | 2064 | (when (and current-thread |
| 2002 | (not (string-equal current-thread gdb-thread-number))) | 2065 | (not (string-equal current-thread gdb-thread-number))) |
| 2003 | ;; Implicitly switch thread (in case previous one dies) | 2066 | ;; Implicitly switch thread (in case previous one dies) |
| @@ -2005,6 +2068,9 @@ FILE is a full path." | |||
| 2005 | (setq gdb-thread-number current-thread)) | 2068 | (setq gdb-thread-number current-thread)) |
| 2006 | (set-marker gdb-thread-position nil) | 2069 | (set-marker gdb-thread-position nil) |
| 2007 | (dolist (thread threads-list) | 2070 | (dolist (thread threads-list) |
| 2071 | (add-to-list 'gdb-threads-list | ||
| 2072 | (cons (gdb-get-field thread 'id) | ||
| 2073 | thread)) | ||
| 2008 | (insert (apply 'format `("%s (%s) %s in %s " | 2074 | (insert (apply 'format `("%s (%s) %s in %s " |
| 2009 | ,@(gdb-get-many-fields thread 'id 'target-id 'state) | 2075 | ,@(gdb-get-many-fields thread 'id 'target-id 'state) |
| 2010 | ,(gdb-get-field thread 'frame 'func)))) | 2076 | ,(gdb-get-field thread 'frame 'func)))) |
| @@ -2071,6 +2137,11 @@ on the current line." | |||
| 2071 | gdb-display-registers-buffer | 2137 | gdb-display-registers-buffer |
| 2072 | "Display registers buffer for the thread at current line.") | 2138 | "Display registers buffer for the thread at current line.") |
| 2073 | 2139 | ||
| 2140 | (def-gdb-thread-buffer-simple-command | ||
| 2141 | gdb-display-disassembly-for-thread | ||
| 2142 | gdb-display-disassembly-buffer | ||
| 2143 | "Display disassembly buffer for the thread at current line.") | ||
| 2144 | |||
| 2074 | (def-gdb-thread-simple-buffer-command | 2145 | (def-gdb-thread-simple-buffer-command |
| 2075 | gdb-frame-stack-for-thread | 2146 | gdb-frame-stack-for-thread |
| 2076 | gdb-frame-stack-buffer | 2147 | gdb-frame-stack-buffer |
| @@ -2089,6 +2160,12 @@ current line.") | |||
| 2089 | "Display a new frame with registers buffer for the thread at | 2160 | "Display a new frame with registers buffer for the thread at |
| 2090 | current line.") | 2161 | current line.") |
| 2091 | 2162 | ||
| 2163 | (def-gdb-thread-buffer-simple-command | ||
| 2164 | gdb-frame-disassembly-for-thread | ||
| 2165 | gdb-frame-disassembly-buffer | ||
| 2166 | "Display a new frame with disassembly buffer for the thread at | ||
| 2167 | current line.") | ||
| 2168 | |||
| 2092 | 2169 | ||
| 2093 | ;;; Memory view | 2170 | ;;; Memory view |
| 2094 | 2171 | ||
| @@ -2449,15 +2526,10 @@ DOC is an optional documentation string." | |||
| 2449 | 'local-map gdb-memory-unit-map))) | 2526 | 'local-map gdb-memory-unit-map))) |
| 2450 | "Header line used in `gdb-memory-mode'.") | 2527 | "Header line used in `gdb-memory-mode'.") |
| 2451 | 2528 | ||
| 2452 | (defun gdb-memory-mode () | 2529 | (define-derived-mode gdb-memory-mode gdb-parent-mode "Memory" |
| 2453 | "Major mode for examining memory. | 2530 | "Major mode for examining memory. |
| 2454 | 2531 | ||
| 2455 | \\{gdb-memory-mode-map}" | 2532 | \\{gdb-memory-mode-map}" |
| 2456 | (kill-all-local-variables) | ||
| 2457 | (setq major-mode 'gdb-memory-mode) | ||
| 2458 | (setq mode-name "Memory") | ||
| 2459 | (use-local-map gdb-memory-mode-map) | ||
| 2460 | (setq buffer-read-only t) | ||
| 2461 | (setq header-line-format gdb-memory-header) | 2533 | (setq header-line-format gdb-memory-header) |
| 2462 | (set (make-local-variable 'font-lock-defaults) | 2534 | (set (make-local-variable 'font-lock-defaults) |
| 2463 | '(gdb-memory-font-lock-keywords)) | 2535 | '(gdb-memory-font-lock-keywords)) |
| @@ -2487,7 +2559,8 @@ DOC is an optional documentation string." | |||
| 2487 | ;;; Disassembly view | 2559 | ;;; Disassembly view |
| 2488 | 2560 | ||
| 2489 | (defun gdb-disassembly-buffer-name () | 2561 | (defun gdb-disassembly-buffer-name () |
| 2490 | (concat "*disassembly of " (gdb-get-target-string) "*")) | 2562 | (gdb-current-context-buffer-name |
| 2563 | (concat "disassembly of " (gdb-get-target-string)))) | ||
| 2491 | 2564 | ||
| 2492 | (def-gdb-display-buffer | 2565 | (def-gdb-display-buffer |
| 2493 | gdb-display-disassembly-buffer | 2566 | gdb-display-disassembly-buffer |
| @@ -2500,10 +2573,11 @@ DOC is an optional documentation string." | |||
| 2500 | "Display disassembly in a new frame.") | 2573 | "Display disassembly in a new frame.") |
| 2501 | 2574 | ||
| 2502 | (def-gdb-auto-update-trigger gdb-invalidate-disassembly | 2575 | (def-gdb-auto-update-trigger gdb-invalidate-disassembly |
| 2503 | (let ((file (or gdb-selected-file gdb-main-file)) | 2576 | (let* ((frame (gdb-current-buffer-frame)) |
| 2504 | (line (or gdb-selected-line 1))) | 2577 | (file (gdb-get-field frame 'file)) |
| 2505 | (if (not file) (error "Disassembly invalidated with no file selected.") | 2578 | (line (gdb-get-field frame 'line))) |
| 2506 | (format "-data-disassemble -f %s -l %d -n -1 -- 0" file line))) | 2579 | (when file |
| 2580 | (format "-data-disassemble -f %s -l %s -n -1 -- 0" file line))) | ||
| 2507 | gdb-disassembly-handler) | 2581 | gdb-disassembly-handler) |
| 2508 | 2582 | ||
| 2509 | (def-gdb-auto-update-handler | 2583 | (def-gdb-auto-update-handler |
| @@ -2539,37 +2613,32 @@ DOC is an optional documentation string." | |||
| 2539 | (define-key map "q" 'kill-this-buffer) | 2613 | (define-key map "q" 'kill-this-buffer) |
| 2540 | map)) | 2614 | map)) |
| 2541 | 2615 | ||
| 2542 | (defun gdb-disassembly-mode () | 2616 | (define-derived-mode gdb-disassembly-mode gdb-parent-mode "Disassembly" |
| 2543 | "Major mode for GDB disassembly information. | 2617 | "Major mode for GDB disassembly information. |
| 2544 | 2618 | ||
| 2545 | \\{gdb-disassembly-mode-map}" | 2619 | \\{gdb-disassembly-mode-map}" |
| 2546 | (kill-all-local-variables) | ||
| 2547 | (setq major-mode 'gdb-disassembly-mode) | ||
| 2548 | (setq mode-name "Disassembly") | ||
| 2549 | (add-to-list 'overlay-arrow-variable-list 'gdb-overlay-arrow-position) | 2620 | (add-to-list 'overlay-arrow-variable-list 'gdb-overlay-arrow-position) |
| 2550 | (setq fringes-outside-margins t) | 2621 | (setq fringes-outside-margins t) |
| 2551 | (setq gdb-overlay-arrow-position (make-marker)) | 2622 | (setq gdb-overlay-arrow-position (make-marker)) |
| 2552 | (use-local-map gdb-disassembly-mode-map) | ||
| 2553 | (setq buffer-read-only t) | ||
| 2554 | (buffer-disable-undo) | ||
| 2555 | (set (make-local-variable 'font-lock-defaults) | 2623 | (set (make-local-variable 'font-lock-defaults) |
| 2556 | '(gdb-disassembly-font-lock-keywords)) | 2624 | '(gdb-disassembly-font-lock-keywords)) |
| 2557 | (run-mode-hooks 'gdb-disassembly-mode-hook) | 2625 | (run-mode-hooks 'gdb-disassembly-mode-hook) |
| 2558 | 'gdb-invalidate-disassembly) | 2626 | 'gdb-invalidate-disassembly) |
| 2559 | 2627 | ||
| 2560 | (defun gdb-disassembly-handler-custom () | 2628 | (defun gdb-disassembly-handler-custom () |
| 2561 | (let* ((res (json-partial-output)) | 2629 | (let* ((pos 1) |
| 2630 | (address (gdb-get-field (gdb-current-buffer-frame) 'addr)) | ||
| 2631 | (res (json-partial-output)) | ||
| 2562 | (instructions (gdb-get-field res 'asm_insns)) | 2632 | (instructions (gdb-get-field res 'asm_insns)) |
| 2563 | (pos 1)) | 2633 | (last-instr (car (last instructions))) |
| 2564 | (let* ((last-instr (car (last instructions))) | 2634 | (column-padding (+ 2 (string-width |
| 2565 | (column-padding (+ 2 (string-width | 2635 | (apply 'format |
| 2566 | (apply 'format | 2636 | `("<%s+%s>:" |
| 2567 | `("<%s+%s>:" | 2637 | ,@(gdb-get-many-fields last-instr 'func-name 'offset))))))) |
| 2568 | ,@(gdb-get-many-fields last-instr 'func-name 'offset))))))) | ||
| 2569 | (dolist (instr instructions) | 2638 | (dolist (instr instructions) |
| 2570 | ;; Put overlay arrow | 2639 | ;; Put overlay arrow |
| 2571 | (when (string-equal (gdb-get-field instr 'address) | 2640 | (when (string-equal (gdb-get-field instr 'address) |
| 2572 | gdb-pc-address) | 2641 | address) |
| 2573 | (progn | 2642 | (progn |
| 2574 | (setq pos (point)) | 2643 | (setq pos (point)) |
| 2575 | (setq fringe-indicator-alist | 2644 | (setq fringe-indicator-alist |
| @@ -2581,20 +2650,24 @@ DOC is an optional documentation string." | |||
| 2581 | (concat | 2650 | (concat |
| 2582 | (gdb-get-field instr 'address) | 2651 | (gdb-get-field instr 'address) |
| 2583 | " " | 2652 | " " |
| 2584 | (gdb-pad-string (apply 'format `("<%s+%s>:" ,@(gdb-get-many-fields instr 'func-name 'offset))) | 2653 | (gdb-pad-string (apply 'format `("<%s+%s>:" ,@(gdb-get-many-fields instr 'func-name 'offset))) |
| 2585 | (- column-padding)) | 2654 | (- column-padding)) |
| 2586 | (gdb-get-field instr 'inst) | 2655 | (gdb-get-field instr 'inst) |
| 2587 | "\n"))) | 2656 | "\n"))) |
| 2588 | (gdb-disassembly-place-breakpoints) | 2657 | (gdb-disassembly-place-breakpoints) |
| 2589 | (let ((window (get-buffer-window (current-buffer) 0))) | 2658 | (let ((window (get-buffer-window (current-buffer) 0))) |
| 2590 | (set-window-point window pos))))) | 2659 | (set-window-point window pos)) |
| 2660 | (setq mode-name | ||
| 2661 | (concat "Disassembly: " | ||
| 2662 | (gdb-get-field (gdb-current-buffer-frame) 'func))))) | ||
| 2591 | 2663 | ||
| 2592 | (defun gdb-disassembly-place-breakpoints () | 2664 | (defun gdb-disassembly-place-breakpoints () |
| 2593 | (gdb-remove-breakpoint-icons (point-min) (point-max)) | 2665 | (gdb-remove-breakpoint-icons (point-min) (point-max)) |
| 2594 | (dolist (breakpoint gdb-breakpoints-list) | 2666 | (dolist (breakpoint gdb-breakpoints-list) |
| 2595 | (let ((bptno (gdb-get-field breakpoint 'number)) | 2667 | (let* ((breakpoint (cdr breakpoint)) |
| 2596 | (flag (gdb-get-field breakpoint 'enabled)) | 2668 | (bptno (gdb-get-field breakpoint 'number)) |
| 2597 | (address (gdb-get-field breakpoint 'addr))) | 2669 | (flag (gdb-get-field breakpoint 'enabled)) |
| 2670 | (address (gdb-get-field breakpoint 'addr))) | ||
| 2598 | (save-excursion | 2671 | (save-excursion |
| 2599 | (goto-char (point-min)) | 2672 | (goto-char (point-min)) |
| 2600 | (if (re-search-forward (concat "^" address) nil t) | 2673 | (if (re-search-forward (concat "^" address) nil t) |
| @@ -2602,16 +2675,11 @@ DOC is an optional documentation string." | |||
| 2602 | 2675 | ||
| 2603 | 2676 | ||
| 2604 | ;;; Breakpoints view | 2677 | ;;; Breakpoints view |
| 2605 | (defun gdb-breakpoints-mode () | 2678 | |
| 2679 | (define-derived-mode gdb-breakpoints-mode gdb-parent-mode "Breakpoints" | ||
| 2606 | "Major mode for gdb breakpoints. | 2680 | "Major mode for gdb breakpoints. |
| 2607 | 2681 | ||
| 2608 | \\{gdb-breakpoints-mode-map}" | 2682 | \\{gdb-breakpoints-mode-map}" |
| 2609 | (kill-all-local-variables) | ||
| 2610 | (setq major-mode 'gdb-breakpoints-mode) | ||
| 2611 | (setq mode-name "Breakpoints") | ||
| 2612 | (use-local-map gdb-breakpoints-mode-map) | ||
| 2613 | (setq buffer-read-only t) | ||
| 2614 | (buffer-disable-undo) | ||
| 2615 | (setq header-line-format gdb-breakpoints-header) | 2683 | (setq header-line-format gdb-breakpoints-header) |
| 2616 | (run-mode-hooks 'gdb-breakpoints-mode-hook) | 2684 | (run-mode-hooks 'gdb-breakpoints-mode-hook) |
| 2617 | 'gdb-invalidate-breakpoints) | 2685 | 'gdb-invalidate-breakpoints) |
| @@ -2750,19 +2818,13 @@ member." | |||
| 2750 | '(("in \\([^ ]+\\) of " (1 font-lock-function-name-face))) | 2818 | '(("in \\([^ ]+\\) of " (1 font-lock-function-name-face))) |
| 2751 | "Font lock keywords used in `gdb-frames-mode'.") | 2819 | "Font lock keywords used in `gdb-frames-mode'.") |
| 2752 | 2820 | ||
| 2753 | (defun gdb-frames-mode () | 2821 | (define-derived-mode gdb-frames-mode gdb-parent-mode "Frames" |
| 2754 | "Major mode for gdb call stack. | 2822 | "Major mode for gdb call stack. |
| 2755 | 2823 | ||
| 2756 | \\{gdb-frames-mode-map}" | 2824 | \\{gdb-frames-mode-map}" |
| 2757 | (kill-all-local-variables) | ||
| 2758 | (setq major-mode 'gdb-frames-mode) | ||
| 2759 | (setq mode-name "Frames") | ||
| 2760 | (setq gdb-stack-position nil) | 2825 | (setq gdb-stack-position nil) |
| 2761 | (add-to-list 'overlay-arrow-variable-list 'gdb-stack-position) | 2826 | (add-to-list 'overlay-arrow-variable-list 'gdb-stack-position) |
| 2762 | (setq truncate-lines t) ;; Make it easier to see overlay arrow. | 2827 | (setq truncate-lines t) ;; Make it easier to see overlay arrow. |
| 2763 | (setq buffer-read-only t) | ||
| 2764 | (buffer-disable-undo) | ||
| 2765 | (use-local-map gdb-frames-mode-map) | ||
| 2766 | (set (make-local-variable 'font-lock-defaults) | 2828 | (set (make-local-variable 'font-lock-defaults) |
| 2767 | '(gdb-frames-font-lock-keywords)) | 2829 | '(gdb-frames-font-lock-keywords)) |
| 2768 | (run-mode-hooks 'gdb-frames-mode-hook) | 2830 | (run-mode-hooks 'gdb-frames-mode-hook) |
| @@ -2844,7 +2906,9 @@ member." | |||
| 2844 | value)) | 2906 | value)) |
| 2845 | (insert | 2907 | (insert |
| 2846 | (concat name "\t" type | 2908 | (concat name "\t" type |
| 2847 | "\t" value "\n")))))) | 2909 | "\t" value "\n")))) |
| 2910 | (setq mode-name | ||
| 2911 | (concat "Locals: " (gdb-get-field (gdb-current-buffer-frame) 'func))))) | ||
| 2848 | 2912 | ||
| 2849 | (defvar gdb-locals-header | 2913 | (defvar gdb-locals-header |
| 2850 | (list | 2914 | (list |
| @@ -2860,17 +2924,11 @@ member." | |||
| 2860 | (define-key map "q" 'kill-this-buffer) | 2924 | (define-key map "q" 'kill-this-buffer) |
| 2861 | map)) | 2925 | map)) |
| 2862 | 2926 | ||
| 2863 | (defun gdb-locals-mode () | 2927 | (define-derived-mode gdb-locals-mode gdb-parent-mode "Locals" |
| 2864 | "Major mode for gdb locals. | 2928 | "Major mode for gdb locals. |
| 2865 | 2929 | ||
| 2866 | \\{gdb-locals-mode-map}" | 2930 | \\{gdb-locals-mode-map}" |
| 2867 | (kill-all-local-variables) | ||
| 2868 | (setq major-mode 'gdb-locals-mode) | ||
| 2869 | (setq mode-name (concat "Locals:" gdb-selected-frame)) | ||
| 2870 | (setq buffer-read-only t) | ||
| 2871 | (buffer-disable-undo) | ||
| 2872 | (setq header-line-format gdb-locals-header) | 2931 | (setq header-line-format gdb-locals-header) |
| 2873 | (use-local-map gdb-locals-mode-map) | ||
| 2874 | (set (make-local-variable 'font-lock-defaults) | 2932 | (set (make-local-variable 'font-lock-defaults) |
| 2875 | '(gdb-locals-font-lock-keywords)) | 2933 | '(gdb-locals-font-lock-keywords)) |
| 2876 | (run-mode-hooks 'gdb-locals-mode-hook) | 2934 | (run-mode-hooks 'gdb-locals-mode-hook) |
| @@ -2928,17 +2986,11 @@ member." | |||
| 2928 | (define-key map "q" 'kill-this-buffer) | 2986 | (define-key map "q" 'kill-this-buffer) |
| 2929 | map)) | 2987 | map)) |
| 2930 | 2988 | ||
| 2931 | (defun gdb-registers-mode () | 2989 | (define-derived-mode gdb-registers-mode gdb-parent-mode "Registers" |
| 2932 | "Major mode for gdb registers. | 2990 | "Major mode for gdb registers. |
| 2933 | 2991 | ||
| 2934 | \\{gdb-registers-mode-map}" | 2992 | \\{gdb-registers-mode-map}" |
| 2935 | (kill-all-local-variables) | ||
| 2936 | (setq major-mode 'gdb-registers-mode) | ||
| 2937 | (setq mode-name "Registers") | ||
| 2938 | (setq header-line-format gdb-locals-header) | 2993 | (setq header-line-format gdb-locals-header) |
| 2939 | (setq buffer-read-only t) | ||
| 2940 | (buffer-disable-undo) | ||
| 2941 | (use-local-map gdb-registers-mode-map) | ||
| 2942 | (run-mode-hooks 'gdb-registers-mode-hook) | 2994 | (run-mode-hooks 'gdb-registers-mode-hook) |
| 2943 | 'gdb-invalidate-registers) | 2995 | 'gdb-invalidate-registers) |
| 2944 | 2996 | ||
| @@ -2996,20 +3048,22 @@ is set in them." | |||
| 2996 | (gdb-force-mode-line-update | 3048 | (gdb-force-mode-line-update |
| 2997 | (propertize "ready" 'face font-lock-variable-name-face))) | 3049 | (propertize "ready" 'face font-lock-variable-name-face))) |
| 2998 | 3050 | ||
| 2999 | (defun gdb-get-selected-frame () | 3051 | (defun gdb-get-main-selected-frame () |
| 3000 | (if (not (gdb-pending-p 'gdb-get-selected-frame)) | 3052 | "Trigger for `gdb-frame-handler' which uses main current |
| 3053 | thread. Called from `gdb-update'." | ||
| 3054 | (if (not (gdb-pending-p 'gdb-get-main-selected-frame)) | ||
| 3001 | (progn | 3055 | (progn |
| 3002 | (gdb-input | 3056 | (gdb-input |
| 3003 | (list (gdb-current-context-command "-stack-info-frame") 'gdb-frame-handler)) | 3057 | (list (gdb-current-context-command "-stack-info-frame") 'gdb-frame-handler)) |
| 3004 | (push 'gdb-get-selected-frame | 3058 | (gdb-add-pending 'gdb-get-main-selected-frame)))) |
| 3005 | gdb-pending-triggers)))) | ||
| 3006 | 3059 | ||
| 3007 | (defun gdb-frame-handler () | 3060 | (defun gdb-frame-handler () |
| 3008 | (gdb-delete-pending 'gdb-get-selected-frame) | 3061 | "Sets `gdb-pc-address', `gdb-selected-frame' and |
| 3062 | `gdb-selected-file' to show overlay arrow in source buffer." | ||
| 3063 | (gdb-delete-pending 'gdb-get-main-selected-frame) | ||
| 3009 | (let ((frame (gdb-get-field (json-partial-output) 'frame))) | 3064 | (let ((frame (gdb-get-field (json-partial-output) 'frame))) |
| 3010 | (when frame | 3065 | (when frame |
| 3011 | (setq gdb-frame-number (gdb-get-field frame 'level)) | 3066 | (setq gdb-frame-number (gdb-get-field frame 'level)) |
| 3012 | (setq gdb-pc-address (gdb-get-field frame 'addr)) | ||
| 3013 | (setq gdb-selected-frame (gdb-get-field frame 'func)) | 3067 | (setq gdb-selected-frame (gdb-get-field frame 'func)) |
| 3014 | (setq gdb-selected-file (gdb-get-field frame 'fullname)) | 3068 | (setq gdb-selected-file (gdb-get-field frame 'fullname)) |
| 3015 | (let ((line (gdb-get-field frame 'line))) | 3069 | (let ((line (gdb-get-field frame 'line))) |
| @@ -3018,12 +3072,6 @@ is set in them." | |||
| 3018 | (when line ; obey the current file only if we have line info | 3072 | (when line ; obey the current file only if we have line info |
| 3019 | (setq gud-last-frame (cons gdb-selected-file gdb-selected-line)) | 3073 | (setq gud-last-frame (cons gdb-selected-file gdb-selected-line)) |
| 3020 | (gud-display-frame))) | 3074 | (gud-display-frame))) |
| 3021 | (if (gdb-get-buffer 'gdb-locals-buffer) | ||
| 3022 | (with-current-buffer (gdb-get-buffer 'gdb-locals-buffer) | ||
| 3023 | (setq mode-name (concat "Locals:" gdb-selected-frame)))) | ||
| 3024 | (if (gdb-get-buffer 'gdb-disassembly-buffer) | ||
| 3025 | (with-current-buffer (gdb-get-buffer 'gdb-disassembly-buffer) | ||
| 3026 | (setq mode-name (concat "Disassembly:" gdb-selected-frame)))) | ||
| 3027 | (if gud-overlay-arrow-position | 3075 | (if gud-overlay-arrow-position |
| 3028 | (let ((buffer (marker-buffer gud-overlay-arrow-position)) | 3076 | (let ((buffer (marker-buffer gud-overlay-arrow-position)) |
| 3029 | (position (marker-position gud-overlay-arrow-position))) | 3077 | (position (marker-position gud-overlay-arrow-position))) |
| @@ -3034,9 +3082,7 @@ is set in them." | |||
| 3034 | nil | 3082 | nil |
| 3035 | '((overlay-arrow . hollow-right-triangle)))) | 3083 | '((overlay-arrow . hollow-right-triangle)))) |
| 3036 | (setq gud-overlay-arrow-position (make-marker)) | 3084 | (setq gud-overlay-arrow-position (make-marker)) |
| 3037 | (set-marker gud-overlay-arrow-position position))))) | 3085 | (set-marker gud-overlay-arrow-position position)))))))) |
| 3038 | (when gdb-selected-line | ||
| 3039 | (gdb-invalidate-disassembly))))) | ||
| 3040 | 3086 | ||
| 3041 | (defvar gdb-prompt-name-regexp "value=\"\\(.*?\\)\"") | 3087 | (defvar gdb-prompt-name-regexp "value=\"\\(.*?\\)\"") |
| 3042 | 3088 | ||