Mercurial > emacs
comparison lisp/progmodes/gdb-mi.el @ 103748:5a1769adb8af
Port memory buffer from gdb-ui.el
(gdb-memory-address): New variable which holds top address of
memory page shown in memory buffer
(gdb-memory-repeat-count, gdb-memory-format, gdb-memory-unit): New
customization variables.
New functions:
(gdb-display-memory-buffer, gdb-frame-memory-buffer): Functions to
display the memory buffer.
(gdb-memory-set-address, gdb-memory-set-repeat-count): Set memory
buffer display parameters.
(def-gdb-memory-format, gdb-memory-format-binary)
(gdb-memory-format-octal, gdb-memory-format-unsigned)
(gdb-memory-format-signed, gdb-memory-format-hexadecimal):
Functions for setting memory buffer format.
(gdb-memory-unit-word, gdb-memory-unit-halfword)
(gdb-memory-unit-giant, gdb-memory-unit-byte): Functions to set
unit size used in memory buffer.
(gdb-memory-show-next-page, gdb-memory-show-previous-page): Switch
to next/previous page of memory buffer.
author | Dmitry Dzhus <dima@sphinx.net.ru> |
---|---|
date | Tue, 07 Jul 2009 16:57:41 +0000 |
parents | 1c5f849edf58 |
children | f3eef698a354 |
comparison
equal
deleted
inserted
replaced
103747:4f648d5b56cd | 103748:5a1769adb8af |
---|---|
89 | 89 |
90 ;; 1) Stack buffer doesn't parse MI output if you stop in a routine without | 90 ;; 1) Stack buffer doesn't parse MI output if you stop in a routine without |
91 ;; line information, e.g., a routine in libc (just a TODO item). | 91 ;; line information, e.g., a routine in libc (just a TODO item). |
92 | 92 |
93 ;; TODO: | 93 ;; TODO: |
94 ;; 1) Use MI command -data-read-memory for memory window. | |
95 ;; 2) Watch windows to work with threads. | 94 ;; 2) Watch windows to work with threads. |
96 ;; 3) Use treebuffer.el instead of the speedbar for watch-expressions? | 95 ;; 3) Use treebuffer.el instead of the speedbar for watch-expressions? |
97 ;; 4) Mark breakpoint locations on scroll-bar of source buffer? | 96 ;; 4) Mark breakpoint locations on scroll-bar of source buffer? |
98 | 97 |
99 ;;; Code: | 98 ;;; Code: |
105 (defvar tool-bar-map) | 104 (defvar tool-bar-map) |
106 (defvar speedbar-initial-expansion-list-name) | 105 (defvar speedbar-initial-expansion-list-name) |
107 | 106 |
108 (defvar gdb-pc-address nil "Initialization for Assembler buffer. | 107 (defvar gdb-pc-address nil "Initialization for Assembler buffer. |
109 Set to \"main\" at start if `gdb-show-main' is t.") | 108 Set to \"main\" at start if `gdb-show-main' is t.") |
109 (defvar gdb-memory-address "main") | |
110 (defvar gdb-memory-last-address nil | |
111 "Last successfully accessed memory address.") | |
112 (defvar gdb-memory-next-page nil | |
113 "Address of next memory page for program memory buffer.") | |
114 (defvar gdb-memory-prev-page nil | |
115 "Address of previous memory page for program memory buffer.") | |
116 | |
110 (defvar gdb-selected-frame nil) | 117 (defvar gdb-selected-frame nil) |
111 (defvar gdb-selected-file nil) | 118 (defvar gdb-selected-file nil) |
112 (defvar gdb-selected-line nil) | 119 (defvar gdb-selected-line nil) |
113 (defvar gdb-frame-number nil) | 120 (defvar gdb-frame-number nil) |
114 (defvar gdb-current-language nil) | 121 (defvar gdb-current-language nil) |
1205 (gdb-invalidate-breakpoints) | 1212 (gdb-invalidate-breakpoints) |
1206 (gdb-invalidate-threads) | 1213 (gdb-invalidate-threads) |
1207 (gdb-get-changed-registers) | 1214 (gdb-get-changed-registers) |
1208 (gdb-invalidate-registers) | 1215 (gdb-invalidate-registers) |
1209 (gdb-invalidate-locals) | 1216 (gdb-invalidate-locals) |
1217 (gdb-invalidate-memory) | |
1210 (when (and (boundp 'speedbar-frame) (frame-live-p speedbar-frame)) | 1218 (when (and (boundp 'speedbar-frame) (frame-live-p speedbar-frame)) |
1211 (dolist (var gdb-var-list) | 1219 (dolist (var gdb-var-list) |
1212 (setcar (nthcdr 5 var) nil)) | 1220 (setcar (nthcdr 5 var) nil)) |
1213 (gdb-var-update))) | 1221 (gdb-var-update))) |
1214 | 1222 |
1859 (gdb-insert-frame-location (fadr-q "thread.frame")) | 1867 (gdb-insert-frame-location (fadr-q "thread.frame")) |
1860 (insert (fadr-format " at ~.frame.addr\n" thread))))) | 1868 (insert (fadr-format " at ~.frame.addr\n" thread))))) |
1861 | 1869 |
1862 | 1870 |
1863 ;;; Memory view | 1871 ;;; Memory view |
1864 (defun gdb-todo-memory () | 1872 |
1873 (defcustom gdb-memory-rows 8 | |
1874 "Number of data rows in memory window." | |
1875 :type 'integer | |
1876 :group 'gud | |
1877 :version "23.2") | |
1878 | |
1879 (defcustom gdb-memory-columns 4 | |
1880 "Number of data columns in memory window." | |
1881 :type 'integer | |
1882 :group 'gud | |
1883 :version "23.2") | |
1884 | |
1885 (defcustom gdb-memory-format "x" | |
1886 "Display format of data items in memory window." | |
1887 :type '(choice (const :tag "Hexadecimal" "x") | |
1888 (const :tag "Signed decimal" "d") | |
1889 (const :tag "Unsigned decimal" "u") | |
1890 (const :tag "Octal" "o") | |
1891 (const :tag "Binary" "t")) | |
1892 :group 'gud | |
1893 :version "22.1") | |
1894 | |
1895 (defcustom gdb-memory-unit 4 | |
1896 "Unit size of data items in memory window." | |
1897 :type '(choice (const :tag "Byte" 1) | |
1898 (const :tag "Halfword" 2) | |
1899 (const :tag "Word" 4) | |
1900 (const :tag "Giant word" 8)) | |
1901 :group 'gud | |
1902 :version "23.2") | |
1903 | |
1904 (gdb-set-buffer-rules 'gdb-memory-buffer | |
1905 'gdb-memory-buffer-name | |
1906 'gdb-memory-mode) | |
1907 | |
1908 (def-gdb-auto-updated-buffer gdb-memory-buffer | |
1909 gdb-invalidate-memory | |
1910 (format "-data-read-memory %s %s %d %d %d\n" | |
1911 gdb-memory-address | |
1912 gdb-memory-format | |
1913 gdb-memory-unit | |
1914 gdb-memory-rows | |
1915 gdb-memory-columns) | |
1916 gdb-read-memory-handler | |
1917 gdb-read-memory-custom) | |
1918 | |
1919 (defun gdb-read-memory-custom () | |
1920 (let* ((res (json-partial-output)) | |
1921 (err-msg (fadr-q "res.msg"))) | |
1922 (if (not err-msg) | |
1923 (let ((memory (fadr-q "res.memory"))) | |
1924 (setq gdb-memory-address (fadr-q "res.addr")) | |
1925 (setq gdb-memory-next-page (fadr-q "res.next-page")) | |
1926 (setq gdb-memory-prev-page (fadr-q "res.prev-page")) | |
1927 (setq gdb-memory-last-address gdb-memory-address) | |
1928 (dolist (row memory) | |
1929 (insert (concat (fadr-q "row.addr") ": ")) | |
1930 (dolist (column (fadr-q "row.data")) | |
1931 (insert (concat column "\t"))) | |
1932 (newline))) | |
1933 (progn | |
1934 (let ((gdb-memory-address gdb-memory-last-address)) | |
1935 (gdb-invalidate-memory) | |
1936 (error err-msg)))))) | |
1937 | |
1938 (defvar gdb-memory-mode-map | |
1939 (let ((map (make-sparse-keymap))) | |
1940 (suppress-keymap map t) | |
1941 (define-key map "q" 'kill-this-buffer) | |
1942 (define-key map "n" 'gdb-memory-show-next-page) | |
1943 (define-key map "p" 'gdb-memory-show-previous-page) | |
1944 (define-key map "a" 'gdb-memory-set-address) | |
1945 (define-key map "t" 'gdb-memory-format-binary) | |
1946 (define-key map "o" 'gdb-memory-format-octal) | |
1947 (define-key map "u" 'gdb-memory-format-unsigned) | |
1948 (define-key map "d" 'gdb-memory-format-signed) | |
1949 (define-key map "x" 'gdb-memory-format-hexadecimal) | |
1950 (define-key map "b" 'gdb-memory-unit-byte) | |
1951 (define-key map "h" 'gdb-memory-unit-halfword) | |
1952 (define-key map "w" 'gdb-memory-unit-word) | |
1953 (define-key map "g" 'gdb-memory-unit-giant) | |
1954 (define-key map "R" 'gdb-memory-set-rows) | |
1955 (define-key map "C" 'gdb-memory-set-columns) | |
1956 map)) | |
1957 | |
1958 (defun gdb-memory-set-address-event (event) | |
1959 "Handle a click on address field in memory buffer header." | |
1960 (interactive "e") | |
1961 (save-selected-window | |
1962 (select-window (posn-window (event-start event))) | |
1963 (gdb-memory-set-address-1))) | |
1964 | |
1965 ;; Non-event version for use within keymap | |
1966 (defun gdb-memory-set-address () | |
1967 "Set the start memory address." | |
1865 (interactive) | 1968 (interactive) |
1866 (message-box | 1969 (let ((arg (read-from-minibuffer "Memory address: "))) |
1867 "TODO: Implement memory buffer using\nMI command -data-read-memory")) | 1970 (setq gdb-memory-address arg)) |
1971 (gdb-invalidate-memory)) | |
1972 | |
1973 (defmacro def-gdb-set-positive-number (name variable echo-string &optional doc) | |
1974 "Define a function NAME which reads new VAR value from minibuffer." | |
1975 `(defun ,name (event) | |
1976 ,(when doc doc) | |
1977 (interactive "e") | |
1978 (save-selected-window | |
1979 (select-window (posn-window (event-start event))) | |
1980 (let* ((arg (read-from-minibuffer ,echo-string)) | |
1981 (count (string-to-number arg))) | |
1982 (if (<= count 0) | |
1983 (error "Positive number only") | |
1984 (customize-set-variable ',variable count) | |
1985 (gdb-invalidate-memory)))))) | |
1986 | |
1987 (def-gdb-set-positive-number | |
1988 gdb-memory-set-rows | |
1989 gdb-memory-rows | |
1990 "Rows: " | |
1991 "Set the number of data rows in memory window.") | |
1992 | |
1993 (def-gdb-set-positive-number | |
1994 gdb-memory-set-columns | |
1995 gdb-memory-columns | |
1996 "Columns: " | |
1997 "Set the number of data columns in memory window.") | |
1998 | |
1999 (defmacro def-gdb-memory-format (name format doc) | |
2000 "Define a function NAME to switch memory buffer to use FORMAT. | |
2001 | |
2002 DOC is an optional documentation string." | |
2003 `(defun ,name () ,(when doc doc) | |
2004 (interactive) | |
2005 (customize-set-variable 'gdb-memory-format ,format) | |
2006 (gdb-invalidate-memory))) | |
2007 | |
2008 (def-gdb-memory-format | |
2009 gdb-memory-format-binary "t" | |
2010 "Set the display format to binary.") | |
2011 | |
2012 (def-gdb-memory-format | |
2013 gdb-memory-format-octal "o" | |
2014 "Set the display format to octal.") | |
2015 | |
2016 (def-gdb-memory-format | |
2017 gdb-memory-format-unsigned "u" | |
2018 "Set the display format to unsigned decimal.") | |
2019 | |
2020 (def-gdb-memory-format | |
2021 gdb-memory-format-signed "d" | |
2022 "Set the display format to decimal.") | |
2023 | |
2024 (def-gdb-memory-format | |
2025 gdb-memory-format-hexadecimal "x" | |
2026 "Set the display format to hexadecimal.") | |
2027 | |
2028 (defvar gdb-memory-format-map | |
2029 (let ((map (make-sparse-keymap))) | |
2030 (define-key map [header-line down-mouse-3] 'gdb-memory-format-menu-1) | |
2031 map) | |
2032 "Keymap to select format in the header line.") | |
2033 | |
2034 (defvar gdb-memory-format-menu (make-sparse-keymap "Format") | |
2035 "Menu of display formats in the header line.") | |
2036 | |
2037 (define-key gdb-memory-format-menu [binary] | |
2038 '(menu-item "Binary" gdb-memory-format-binary | |
2039 :button (:radio . (equal gdb-memory-format "t")))) | |
2040 (define-key gdb-memory-format-menu [octal] | |
2041 '(menu-item "Octal" gdb-memory-format-octal | |
2042 :button (:radio . (equal gdb-memory-format "o")))) | |
2043 (define-key gdb-memory-format-menu [unsigned] | |
2044 '(menu-item "Unsigned Decimal" gdb-memory-format-unsigned | |
2045 :button (:radio . (equal gdb-memory-format "u")))) | |
2046 (define-key gdb-memory-format-menu [signed] | |
2047 '(menu-item "Signed Decimal" gdb-memory-format-signed | |
2048 :button (:radio . (equal gdb-memory-format "d")))) | |
2049 (define-key gdb-memory-format-menu [hexadecimal] | |
2050 '(menu-item "Hexadecimal" gdb-memory-format-hexadecimal | |
2051 :button (:radio . (equal gdb-memory-format "x")))) | |
2052 | |
2053 (defun gdb-memory-format-menu (event) | |
2054 (interactive "@e") | |
2055 (x-popup-menu event gdb-memory-format-menu)) | |
2056 | |
2057 (defun gdb-memory-format-menu-1 (event) | |
2058 (interactive "e") | |
2059 (save-selected-window | |
2060 (select-window (posn-window (event-start event))) | |
2061 (let* ((selection (gdb-memory-format-menu event)) | |
2062 (binding (and selection (lookup-key gdb-memory-format-menu | |
2063 (vector (car selection)))))) | |
2064 (if binding (call-interactively binding))))) | |
2065 | |
2066 (defun gdb-memory-unit-giant () | |
2067 "Set the unit size to giant words (eight bytes)." | |
2068 (interactive) | |
2069 (customize-set-variable 'gdb-memory-unit 8) | |
2070 (gdb-invalidate-memory)) | |
2071 | |
2072 (defun gdb-memory-unit-word () | |
2073 "Set the unit size to words (four bytes)." | |
2074 (interactive) | |
2075 (customize-set-variable 'gdb-memory-unit 4) | |
2076 (gdb-invalidate-memory)) | |
2077 | |
2078 (defun gdb-memory-unit-halfword () | |
2079 "Set the unit size to halfwords (two bytes)." | |
2080 (interactive) | |
2081 (customize-set-variable 'gdb-memory-unit 2) | |
2082 (gdb-invalidate-memory)) | |
2083 | |
2084 (defun gdb-memory-unit-byte () | |
2085 "Set the unit size to bytes." | |
2086 (interactive) | |
2087 (customize-set-variable 'gdb-memory-unit 1) | |
2088 (gdb-invalidate-memory)) | |
2089 | |
2090 (defmacro def-gdb-memory-show-page (name address-var &optional doc) | |
2091 "Define a function NAME which show new address in memory buffer. | |
2092 | |
2093 The defined function switches Memory buffer to show address | |
2094 stored in ADDRESS-VAR variable. | |
2095 | |
2096 DOC is an optional documentation string." | |
2097 `(defun ,name | |
2098 ,(when doc doc) | |
2099 (interactive) | |
2100 (let ((gdb-memory-address ,address-var)) | |
2101 (gdb-invalidate-memory)))) | |
2102 | |
2103 (def-gdb-memory-show-page gdb-memory-show-previous-page | |
2104 gdb-memory-prev-page) | |
2105 | |
2106 (def-gdb-memory-show-page gdb-memory-show-next-page | |
2107 gdb-memory-next-page) | |
2108 | |
2109 (defvar gdb-memory-unit-map | |
2110 (let ((map (make-sparse-keymap))) | |
2111 (define-key map [header-line down-mouse-3] 'gdb-memory-unit-menu-1) | |
2112 map) | |
2113 "Keymap to select units in the header line.") | |
2114 | |
2115 (defvar gdb-memory-unit-menu (make-sparse-keymap "Unit") | |
2116 "Menu of units in the header line.") | |
2117 | |
2118 (define-key gdb-memory-unit-menu [giantwords] | |
2119 '(menu-item "Giant words" gdb-memory-unit-giant | |
2120 :button (:radio . (equal gdb-memory-unit 8)))) | |
2121 (define-key gdb-memory-unit-menu [words] | |
2122 '(menu-item "Words" gdb-memory-unit-word | |
2123 :button (:radio . (equal gdb-memory-unit 4)))) | |
2124 (define-key gdb-memory-unit-menu [halfwords] | |
2125 '(menu-item "Halfwords" gdb-memory-unit-halfword | |
2126 :button (:radio . (equal gdb-memory-unit 2)))) | |
2127 (define-key gdb-memory-unit-menu [bytes] | |
2128 '(menu-item "Bytes" gdb-memory-unit-byte | |
2129 :button (:radio . (equal gdb-memory-unit 1)))) | |
2130 | |
2131 (defun gdb-memory-unit-menu (event) | |
2132 (interactive "@e") | |
2133 (x-popup-menu event gdb-memory-unit-menu)) | |
2134 | |
2135 (defun gdb-memory-unit-menu-1 (event) | |
2136 (interactive "e") | |
2137 (save-selected-window | |
2138 (select-window (posn-window (event-start event))) | |
2139 (let* ((selection (gdb-memory-unit-menu event)) | |
2140 (binding (and selection (lookup-key gdb-memory-unit-menu | |
2141 (vector (car selection)))))) | |
2142 (if binding (call-interactively binding))))) | |
2143 | |
2144 ;;from make-mode-line-mouse-map | |
2145 (defun gdb-make-header-line-mouse-map (mouse function) "\ | |
2146 Return a keymap with single entry for mouse key MOUSE on the header line. | |
2147 MOUSE is defined to run function FUNCTION with no args in the buffer | |
2148 corresponding to the mode line clicked." | |
2149 (let ((map (make-sparse-keymap))) | |
2150 (define-key map (vector 'header-line mouse) function) | |
2151 (define-key map (vector 'header-line 'down-mouse-1) 'ignore) | |
2152 map)) | |
2153 | |
2154 (defvar gdb-memory-font-lock-keywords | |
2155 '(;; <__function.name+n> | |
2156 ("<\\(\\(\\sw\\|[_.]\\)+\\)\\(\\+[0-9]+\\)?>" (1 font-lock-function-name-face)) | |
2157 ) | |
2158 "Font lock keywords used in `gdb-memory-mode'.") | |
2159 | |
2160 (defvar gdb-memory-header | |
2161 '(:eval | |
2162 (concat | |
2163 "Start address[" | |
2164 (propertize "-" | |
2165 'face font-lock-warning-face | |
2166 'help-echo "mouse-1: decrement address" | |
2167 'mouse-face 'mode-line-highlight | |
2168 'local-map (gdb-make-header-line-mouse-map | |
2169 'mouse-1 | |
2170 #'gdb-memory-show-previous-page)) | |
2171 "|" | |
2172 (propertize "+" | |
2173 'face font-lock-warning-face | |
2174 'help-echo "mouse-1: increment address" | |
2175 'mouse-face 'mode-line-highlight | |
2176 'local-map (gdb-make-header-line-mouse-map | |
2177 'mouse-1 | |
2178 #'gdb-memory-show-next-page)) | |
2179 "]: " | |
2180 (propertize gdb-memory-address | |
2181 'face font-lock-warning-face | |
2182 'help-echo "mouse-1: set start address" | |
2183 'mouse-face 'mode-line-highlight | |
2184 'local-map (gdb-make-header-line-mouse-map | |
2185 'mouse-1 | |
2186 #'gdb-memory-set-address-event)) | |
2187 " Rows: " | |
2188 (propertize (number-to-string gdb-memory-rows) | |
2189 'face font-lock-warning-face | |
2190 'help-echo "mouse-1: set number of columns" | |
2191 'mouse-face 'mode-line-highlight | |
2192 'local-map (gdb-make-header-line-mouse-map | |
2193 'mouse-1 | |
2194 #'gdb-memory-set-rows)) | |
2195 " Columns: " | |
2196 (propertize (number-to-string gdb-memory-columns) | |
2197 'face font-lock-warning-face | |
2198 'help-echo "mouse-1: set number of columns" | |
2199 'mouse-face 'mode-line-highlight | |
2200 'local-map (gdb-make-header-line-mouse-map | |
2201 'mouse-1 | |
2202 #'gdb-memory-set-columns)) | |
2203 " Display Format: " | |
2204 (propertize gdb-memory-format | |
2205 'face font-lock-warning-face | |
2206 'help-echo "mouse-3: select display format" | |
2207 'mouse-face 'mode-line-highlight | |
2208 'local-map gdb-memory-format-map) | |
2209 " Unit Size: " | |
2210 (propertize (number-to-string gdb-memory-unit) | |
2211 'face font-lock-warning-face | |
2212 'help-echo "mouse-3: select unit size" | |
2213 'mouse-face 'mode-line-highlight | |
2214 'local-map gdb-memory-unit-map))) | |
2215 "Header line used in `gdb-memory-mode'.") | |
2216 | |
2217 (defun gdb-memory-mode () | |
2218 "Major mode for examining memory. | |
2219 | |
2220 \\{gdb-memory-mode-map}" | |
2221 (kill-all-local-variables) | |
2222 (setq major-mode 'gdb-memory-mode) | |
2223 (setq mode-name "Memory") | |
2224 (use-local-map gdb-memory-mode-map) | |
2225 (setq buffer-read-only t) | |
2226 (setq header-line-format gdb-memory-header) | |
2227 (set (make-local-variable 'font-lock-defaults) | |
2228 '(gdb-memory-font-lock-keywords)) | |
2229 (run-mode-hooks 'gdb-memory-mode-hook) | |
2230 'gdb-invalidate-memory) | |
2231 | |
2232 (defun gdb-memory-buffer-name () | |
2233 (with-current-buffer gud-comint-buffer | |
2234 (concat "*memory of " (gdb-get-target-string) "*"))) | |
2235 | |
2236 (def-gdb-display-buffer | |
2237 gdb-display-memory-buffer | |
2238 'gdb-memory-buffer | |
2239 "Display memory contents.") | |
2240 | |
2241 (defun gdb-frame-memory-buffer () | |
2242 "Display memory contents in a new frame." | |
2243 (interactive) | |
2244 (let* ((special-display-regexps (append special-display-regexps '(".*"))) | |
2245 (special-display-frame-alist | |
2246 (cons '(left-fringe . 0) | |
2247 (cons '(right-fringe . 0) | |
2248 (cons '(width . 83) gdb-frame-parameters))))) | |
2249 (display-buffer (gdb-get-buffer-create 'gdb-memory-buffer)))) | |
2250 | |
1868 | 2251 |
1869 ;;; Disassembly view | 2252 ;;; Disassembly view |
1870 | 2253 |
1871 (defun gdb-disassembly-buffer-name () | 2254 (defun gdb-disassembly-buffer-name () |
1872 (concat "*disassembly of " (gdb-get-target-string) "*")) | 2255 (concat "*disassembly of " (gdb-get-target-string) "*")) |