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) "*"))