aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Dzhus2009-08-04 14:19:08 +0000
committerDmitry Dzhus2009-08-04 14:19:08 +0000
commit9e919ceebc9dd5f177d37886e10bfcce0de6664b (patch)
treea066192379144e7481910eb22d68e7ed2ab40853
parente70866834ebd63f1647a4395cafb1d50ebd927d3 (diff)
downloademacs-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/ChangeLog6
-rw-r--r--lisp/progmodes/gdb-mi.el274
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
392009-08-04 Michael Albinus <michael.albinus@gmx.de> 452009-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.
111Set 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
124Invalidation triggers use this variable to query GDB for 122Invalidation triggers use this variable to query GDB for
125information on the specified thread. 123information on the specified thread by wrapping GDB/MI commands
124in `gdb-current-context-command'.
126 125
127This variable may be updated implicitly by GDB via 126This 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
143Keys are thread numbers (in strings) and values are structures as
144returned 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
150Keys are breakpoint numbers (in string) and values are structures
151as 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
146variable. Each element contains the same fields as \"body\"
147member 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
150Emacs can't find.") 166Emacs 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
926In that buffer, `gdb-buffer-type' must be equal to KEY and 953In 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
929When 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
1265SUBSCRIBER must be a pair, where cdr is a function of one 1310SUBSCRIBER must be a pair, where cdr is a function of one
1266argument (see `gdb-emit-signal')." 1311argument (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
1634HANDLER-NAME as its handler. HANDLER-NAME is bound to current
1635buffer with `gdb-bind-function-to-buffer'.
1636
1637Normally the trigger defined by this command must be called from
1638the buffer where HANDLER-NAME must work. This should be done so
1639that buffer-local thread number may be used in GDB-COMMAND (by
1640calling `gdb-current-context-command').
1641`gdb-bind-function-to-buffer' is used to achieve this, see how
1642it's done in `gdb-get-buffer-create'.
1643
1644Triggers defined by this command are meant to be used as a
1645trigger 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
1614TRIGGER-NAME trigger is defined to send GDB-COMMAND. 1674TRIGGER-NAME trigger is defined to send GDB-COMMAND. See
1675`def-gdb-auto-update-trigger'.
1615 1676
1616HANDLER-NAME handler uses customization of CUSTOM-DEFUN." 1677HANDLER-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
2090current line.") 2161current 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
2167current 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
3053thread. 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