comparison lisp/progmodes/gdb-mi.el @ 103752:dcd3d86fcf81

* progmodes/gdb-mi.el (gdb-init-1): Disassembly buffer mode name may contain frame information, so `string-match' should be used. (gdb-update): Disassembly is invalidated through `gdb-get-selected-frame'. (gdb-pad-string): New function to pad string with spaces. (gdb-invalidate-disassembly): Invalidate only if the buffer exists. (gdb-disassembly-handler-custom): Column alignment. (gdb-disassembly-place-breakpoints): Clear old breakpoints before placing new ones. (gdb-toggle-breakpoint, gdb-delete-breakpoint): Now work from the end of line, too. (gdb-frame-handler): Match convention to for disassembly buffer mode name.
author Dmitry Dzhus <dima@sphinx.net.ru>
date Tue, 07 Jul 2009 17:36:42 +0000
parents 47e338b0e07b
children bd7c204d425b
comparison
equal deleted inserted replaced
103751:47e338b0e07b 103752:dcd3d86fcf81
5 ;; Author: Nick Roberts <nickrob@gnu.org> 5 ;; Author: Nick Roberts <nickrob@gnu.org>
6 ;; Maintainer: FSF 6 ;; Maintainer: FSF
7 ;; Keywords: unix, tools 7 ;; Keywords: unix, tools
8 8
9 ;; This file is part of GNU Emacs. 9 ;; This file is part of GNU Emacs.
10
11 ;; Homepage: http://www.emacswiki.org/emacs/GDB-MI
10 12
11 ;; GNU Emacs is free software: you can redistribute it and/or modify 13 ;; GNU Emacs is free software: you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by 14 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation, either version 3 of the License, or 15 ;; the Free Software Foundation, either version 3 of the License, or
14 ;; (at your option) any later version. 16 ;; (at your option) any later version.
386 (setq gud-running nil) 388 (setq gud-running nil)
387 (gdb-update) 389 (gdb-update)
388 (run-hooks 'gdb-mode-hook)) 390 (run-hooks 'gdb-mode-hook))
389 391
390 (defun gdb-init-1 () 392 (defun gdb-init-1 ()
391 (gud-def gud-break (if (not (string-equal mode-name "Disassembly")) 393 (gud-def gud-break (if (not (string-match "Disassembly" mode-name))
392 (gud-call "break %f:%l" arg) 394 (gud-call "break %f:%l" arg)
393 (save-excursion 395 (save-excursion
394 (beginning-of-line) 396 (beginning-of-line)
395 (forward-char 2) 397 (forward-char 2)
396 (gud-call "break *%a" arg))) 398 (gud-call "break *%a" arg)))
397 "\C-b" "Set breakpoint at current line or address.") 399 "\C-b" "Set breakpoint at current line or address.")
398 ;; 400 ;;
399 (gud-def gud-remove (if (not (string-equal mode-name "Disassembly")) 401 (gud-def gud-remove (if (not (string-match "Disassembly" mode-name))
400 (gud-call "clear %f:%l" arg) 402 (gud-call "clear %f:%l" arg)
401 (save-excursion 403 (save-excursion
402 (beginning-of-line) 404 (beginning-of-line)
403 (forward-char 2) 405 (forward-char 2)
404 (gud-call "clear *%a" arg))) 406 (gud-call "clear *%a" arg)))
405 "\C-d" "Remove breakpoint at current line or address.") 407 "\C-d" "Remove breakpoint at current line or address.")
406 ;; 408 ;;
407 (gud-def gud-until (if (not (string-equal mode-name "Disassembly")) 409 (gud-def gud-until (if (not (string-match "Disassembly" mode-name))
408 (gud-call "-exec-until %f:%l" arg) 410 (gud-call "-exec-until %f:%l" arg)
409 (save-excursion 411 (save-excursion
410 (beginning-of-line) 412 (beginning-of-line)
411 (forward-char 2) 413 (forward-char 2)
412 (gud-call "-exec-until *%a" arg))) 414 (gud-call "-exec-until *%a" arg)))
1218 (gdb-invalidate-breakpoints) 1220 (gdb-invalidate-breakpoints)
1219 (gdb-invalidate-threads) 1221 (gdb-invalidate-threads)
1220 (gdb-get-changed-registers) 1222 (gdb-get-changed-registers)
1221 (gdb-invalidate-registers) 1223 (gdb-invalidate-registers)
1222 (gdb-invalidate-locals) 1224 (gdb-invalidate-locals)
1223 (gdb-invalidate-disassembly)
1224 (gdb-invalidate-memory) 1225 (gdb-invalidate-memory)
1225 (when (and (boundp 'speedbar-frame) (frame-live-p speedbar-frame)) 1226 (when (and (boundp 'speedbar-frame) (frame-live-p speedbar-frame))
1226 (dolist (var gdb-var-list) 1227 (dolist (var gdb-var-list)
1227 (setcar (nthcdr 5 var) nil)) 1228 (setcar (nthcdr 5 var) nil))
1228 (gdb-var-update))) 1229 (gdb-var-update)))
1464 (insert "}") 1465 (insert "}")
1465 (goto-char (point-min)) 1466 (goto-char (point-min))
1466 (let ((json-array-type 'list)) 1467 (let ((json-array-type 'list))
1467 (json-read)))) 1468 (json-read))))
1468 1469
1470 (defun gdb-pad-string (string padding)
1471 (format (concat "%" (number-to-string padding) "s") string))
1472
1469 (defalias 'gdb-get-field 'bindat-get-field) 1473 (defalias 'gdb-get-field 'bindat-get-field)
1470 1474
1471 (defun gdb-get-many-fields (struct &rest fields) 1475 (defun gdb-get-many-fields (struct &rest fields)
1472 "Return a list of FIELDS values from STRUCT." 1476 "Return a list of FIELDS values from STRUCT."
1473 (let ((values)) 1477 (let ((values))
1500 (delq ',trigger 1504 (delq ',trigger
1501 gdb-pending-triggers)) 1505 gdb-pending-triggers))
1502 (let ((buf (gdb-get-buffer ',buf-key))) 1506 (let ((buf (gdb-get-buffer ',buf-key)))
1503 (and buf 1507 (and buf
1504 (with-current-buffer buf 1508 (with-current-buffer buf
1505 (let* ((window (get-buffer-window buf 0)) 1509 (let*((buffer-read-only nil))
1506 (start (window-start window))
1507 (p (window-point window))
1508 (buffer-read-only nil))
1509 (erase-buffer) 1510 (erase-buffer)
1510 (set-window-start window start)
1511 (set-window-point window p)
1512 (,custom-defun))))))) 1511 (,custom-defun)))))))
1513 1512
1514 (defmacro def-gdb-auto-updated-buffer (buf-key 1513 (defmacro def-gdb-auto-updated-buffer (buf-key
1515 trigger-name gdb-command 1514 trigger-name gdb-command
1516 output-handler-name custom-defun) 1515 output-handler-name custom-defun)
1567 (insert 1566 (insert
1568 (concat " in " 1567 (concat " in "
1569 (propertize (gdb-get-field breakpoint 'func) 1568 (propertize (gdb-get-field breakpoint 'func)
1570 'face font-lock-function-name-face))) 1569 'face font-lock-function-name-face)))
1571 (gdb-insert-frame-location breakpoint))) 1570 (gdb-insert-frame-location breakpoint)))
1572 (at (insert at)) 1571 (at (insert (concat " " at)))
1573 (t (insert (gdb-get-field breakpoint 'original-location))))) 1572 (t (insert (gdb-get-field breakpoint 'original-location)))))
1574 (add-text-properties (line-beginning-position) 1573 (add-text-properties (line-beginning-position)
1575 (line-end-position) 1574 (line-end-position)
1576 `(gdb-breakpoint ,breakpoint 1575 `(gdb-breakpoint ,breakpoint
1577 mouse-face highlight 1576 mouse-face highlight
1901 gdb-memory-rows 1900 gdb-memory-rows
1902 gdb-memory-columns) 1901 gdb-memory-columns)
1903 gdb-read-memory-handler 1902 gdb-read-memory-handler
1904 gdb-read-memory-custom) 1903 gdb-read-memory-custom)
1905 1904
1905 (defun gdb-memory-column-width (size format)
1906 "Return length of string with memory unit of SIZE in FORMAT.
1907
1908 SIZE is in bytes, as in `gdb-memory-unit'. FORMAT is a string as
1909 in `gdb-memory-format'."
1910 (let ((format-base (cdr (assoc format
1911 '(("x" . 16)
1912 ("d" . 10) ("u" . 10)
1913 ("o" . 8)
1914 ("t" . 2))))))
1915 (if format-base
1916 (let ((res (ceiling (log (expt 2.0 (* size 8)) format-base))))
1917 (cond ((string-equal format "x")
1918 (+ 2 res)) ; hexadecimal numbers have 0x in front
1919 ((or (string-equal format "d")
1920 (string-equal format "o"))
1921 (1+ res))
1922 (t res)))
1923 (error "Unknown format"))))
1924
1906 (defun gdb-read-memory-custom () 1925 (defun gdb-read-memory-custom ()
1907 (let* ((res (json-partial-output)) 1926 (let* ((res (json-partial-output))
1908 (err-msg (gdb-get-field res 'msg))) 1927 (err-msg (gdb-get-field res 'msg)))
1909 (if (not err-msg) 1928 (if (not err-msg)
1910 (let ((memory (gdb-get-field res 'memory))) 1929 (let ((memory (gdb-get-field res 'memory)))
1911 (setq gdb-memory-address (gdb-get-field res 'addr)) 1930 (setq gdb-memory-address (gdb-get-field res 'addr))
1912 (setq gdb-memory-next-page (gdb-get-field res 'next-page)) 1931 (setq gdb-memory-next-page (gdb-get-field res 'next-page))
1913 (setq gdb-memory-prev-page (gdb-get-field res 'prev-page)) 1932 (setq gdb-memory-prev-page (gdb-get-field res 'prev-page))
1914 (setq gdb-memory-last-address gdb-memory-address) 1933 (setq gdb-memory-last-address gdb-memory-address)
1915 (dolist (row memory) 1934 (dolist (row memory)
1916 (insert (concat (gdb-get-field row 'addr) ": ")) 1935 (insert (concat (gdb-get-field row 'addr) ":"))
1917 (dolist (column (gdb-get-field row 'data)) 1936 (dolist (column (gdb-get-field row 'data))
1918 (insert (concat column "\t"))) 1937 (insert (gdb-pad-string column
1938 (+ 2 (gdb-memory-column-width
1939 gdb-memory-unit
1940 gdb-memory-format)))))
1919 (newline))) 1941 (newline)))
1920 ;; Show last page instead of empty buffer when out of bounds 1942 ;; Show last page instead of empty buffer when out of bounds
1921 (progn 1943 (progn
1922 (let ((gdb-memory-address gdb-memory-last-address)) 1944 (let ((gdb-memory-address gdb-memory-last-address))
1923 (gdb-invalidate-memory) 1945 (gdb-invalidate-memory)
2253 (gdb-set-buffer-rules 'gdb-disassembly-buffer 2275 (gdb-set-buffer-rules 'gdb-disassembly-buffer
2254 'gdb-disassembly-buffer-name 2276 'gdb-disassembly-buffer-name
2255 'gdb-disassembly-mode) 2277 'gdb-disassembly-mode)
2256 2278
2257 (def-gdb-auto-update-trigger gdb-invalidate-disassembly 2279 (def-gdb-auto-update-trigger gdb-invalidate-disassembly
2258 (gdb-get-buffer-create 'gdb-disassembly-buffer) 2280 (gdb-get-buffer 'gdb-disassembly-buffer)
2259 (let ((file (or gdb-selected-file gdb-main-file)) 2281 (let ((file (or gdb-selected-file gdb-main-file))
2260 (line (or gdb-selected-line 1))) 2282 (line (or gdb-selected-line 1)))
2261 (if file 2283 (if (not file) (error "Disassembly invalidated with no file selected.")
2262 (format "-data-disassemble -f %s -l %d -n -1 -- 0\n" file line) 2284 (format "-data-disassemble -f %s -l %d -n -1 -- 0\n" file line)))
2263 ""))
2264 gdb-disassembly-handler) 2285 gdb-disassembly-handler)
2265 2286
2266 (def-gdb-auto-update-handler 2287 (def-gdb-auto-update-handler
2267 gdb-disassembly-handler 2288 gdb-disassembly-handler
2268 gdb-invalidate-disassembly 2289 gdb-invalidate-disassembly
2306 (run-mode-hooks 'gdb-disassembly-mode-hook) 2327 (run-mode-hooks 'gdb-disassembly-mode-hook)
2307 'gdb-invalidate-disassembly) 2328 'gdb-invalidate-disassembly)
2308 2329
2309 (defun gdb-disassembly-handler-custom () 2330 (defun gdb-disassembly-handler-custom ()
2310 (let* ((res (json-partial-output)) 2331 (let* ((res (json-partial-output))
2311 (instructions (gdb-get-field res 'asm_insns))) 2332 (instructions (gdb-get-field res 'asm_insns))
2312 (dolist (instr instructions) 2333 (pos 1))
2334 (let* ((last-instr (car (last instructions)))
2335 (column-padding (+ 2 (string-width
2336 (apply 'format
2337 `("<%s+%s>:"
2338 ,@(gdb-get-many-fields last-instr 'func-name 'offset)))))))
2339 (dolist (instr instructions)
2313 ;; Put overlay arrow 2340 ;; Put overlay arrow
2314 (when (string-equal (gdb-get-field instr 'address) 2341 (when (string-equal (gdb-get-field instr 'address)
2315 gdb-pc-address) 2342 gdb-pc-address)
2316 (progn 2343 (progn
2344 (setq pos (point))
2317 (setq fringe-indicator-alist 2345 (setq fringe-indicator-alist
2318 (if (string-equal gdb-frame-number "0") 2346 (if (string-equal gdb-frame-number "0")
2319 nil 2347 nil
2320 '((overlay-arrow . hollow-right-triangle)))) 2348 '((overlay-arrow . hollow-right-triangle))))
2321 (set-marker gdb-overlay-arrow-position (point)))) 2349 (set-marker gdb-overlay-arrow-position (point))))
2322 (insert (apply 'format `("%s <%s+%s>:\t%s\n" 2350 (insert
2323 ,@(gdb-get-many-fields instr 'address 'func-name 'offset 'inst)))))) 2351 (concat
2324 (gdb-disassembly-place-breakpoints)) 2352 (gdb-get-field instr 'address)
2353 " "
2354 (gdb-pad-string (apply 'format `("<%s+%s>:" ,@(gdb-get-many-fields instr 'func-name 'offset)))
2355 (- column-padding))
2356 (gdb-get-field instr 'inst)
2357 "\n")))
2358 (gdb-disassembly-place-breakpoints)
2359 (let ((window (get-buffer-window (current-buffer) 0)))
2360 (set-window-point window pos)))))
2325 2361
2326 (defun gdb-disassembly-place-breakpoints () 2362 (defun gdb-disassembly-place-breakpoints ()
2363 (gdb-remove-breakpoint-icons (point-min) (point-max))
2327 (dolist (breakpoint gdb-breakpoints-list) 2364 (dolist (breakpoint gdb-breakpoints-list)
2328 (let ((bptno (gdb-get-field breakpoint 'number)) 2365 (let ((bptno (gdb-get-field breakpoint 'number))
2329 (flag (gdb-get-field breakpoint 'enabled)) 2366 (flag (gdb-get-field breakpoint 'enabled))
2330 (address (gdb-get-field breakpoint 'addr))) 2367 (address (gdb-get-field breakpoint 'addr)))
2331 (save-excursion 2368 (save-excursion
2384 2421
2385 (defun gdb-toggle-breakpoint () 2422 (defun gdb-toggle-breakpoint ()
2386 "Enable/disable breakpoint at current line of breakpoints buffer." 2423 "Enable/disable breakpoint at current line of breakpoints buffer."
2387 (interactive) 2424 (interactive)
2388 (save-excursion 2425 (save-excursion
2426 (beginning-of-line)
2389 (let ((breakpoint (get-text-property (point) 'gdb-breakpoint))) 2427 (let ((breakpoint (get-text-property (point) 'gdb-breakpoint)))
2390 (if breakpoint 2428 (if breakpoint
2391 (gud-basic-call 2429 (gud-basic-call
2392 (concat (if (string-equal "y" (gdb-get-field breakpoint 'enabled)) 2430 (concat (if (string-equal "y" (gdb-get-field breakpoint 'enabled))
2393 "-break-disable " 2431 "-break-disable "
2396 (error "Not recognized as break/watchpoint line"))))) 2434 (error "Not recognized as break/watchpoint line")))))
2397 2435
2398 (defun gdb-delete-breakpoint () 2436 (defun gdb-delete-breakpoint ()
2399 "Delete the breakpoint at current line of breakpoints buffer." 2437 "Delete the breakpoint at current line of breakpoints buffer."
2400 (interactive) 2438 (interactive)
2439 (save-excursion
2440 (beginning-of-line)
2401 (let ((breakpoint (get-text-property (point) 'gdb-breakpoint))) 2441 (let ((breakpoint (get-text-property (point) 'gdb-breakpoint)))
2402 (if breakpoint 2442 (if breakpoint
2403 (gud-basic-call (concat "-break-delete " (gdb-get-field breakpoint 'number))) 2443 (gud-basic-call (concat "-break-delete " (gdb-get-field breakpoint 'number)))
2404 (error "Not recognized as break/watchpoint line")))) 2444 (error "Not recognized as break/watchpoint line")))))
2405 2445
2406 (defun gdb-goto-breakpoint (&optional event) 2446 (defun gdb-goto-breakpoint (&optional event)
2407 "Go to the location of breakpoint at current line of 2447 "Go to the location of breakpoint at current line of
2408 breakpoints buffer." 2448 breakpoints buffer."
2409 (interactive (list last-input-event)) 2449 (interactive (list last-input-event))
2410 (if event (posn-set-point (event-end event))) 2450 (if event (posn-set-point (event-end event)))
2411 ;; Hack to stop gdb-goto-breakpoint displaying in GUD buffer. 2451 ;; Hack to stop gdb-goto-breakpoint displaying in GUD buffer.
2412 (let ((window (get-buffer-window gud-comint-buffer))) 2452 (let ((window (get-buffer-window gud-comint-buffer)))
2413 (if window (save-selected-window (select-window window)))) 2453 (if window (save-selected-window (select-window window))))
2454 (save-excursion
2455 (beginning-of-line)
2414 (let ((breakpoint (get-text-property (point) 'gdb-breakpoint))) 2456 (let ((breakpoint (get-text-property (point) 'gdb-breakpoint)))
2415 (if breakpoint 2457 (if breakpoint
2416 (let ((bptno (gdb-get-field breakpoint 'number)) 2458 (let ((bptno (gdb-get-field breakpoint 'number))
2417 (file (gdb-get-field breakpoint 'file)) 2459 (file (gdb-get-field breakpoint 'file))
2418 (line (gdb-get-field breakpoint 'line))) 2460 (line (gdb-get-field breakpoint 'line)))
2424 (display-buffer buffer)))) 2466 (display-buffer buffer))))
2425 (setq gdb-source-window window) 2467 (setq gdb-source-window window)
2426 (with-current-buffer buffer 2468 (with-current-buffer buffer
2427 (goto-line (string-to-number line)) 2469 (goto-line (string-to-number line))
2428 (set-window-point window (point)))))) 2470 (set-window-point window (point))))))
2429 (error "Not recognized as break/watchpoint line")))) 2471 (error "Not recognized as break/watchpoint line")))))
2430 2472
2431 2473
2432 ;; Frames buffer. This displays a perpetually correct bactrack trace. 2474 ;; Frames buffer. This displays a perpetually correct bactrack trace.
2433 ;; 2475 ;;
2434 (gdb-set-buffer-rules 'gdb-stack-buffer 2476 (gdb-set-buffer-rules 'gdb-stack-buffer
2870 (if (gdb-get-buffer 'gdb-locals-buffer) 2912 (if (gdb-get-buffer 'gdb-locals-buffer)
2871 (with-current-buffer (gdb-get-buffer 'gdb-locals-buffer) 2913 (with-current-buffer (gdb-get-buffer 'gdb-locals-buffer)
2872 (setq mode-name (concat "Locals:" gdb-selected-frame)))) 2914 (setq mode-name (concat "Locals:" gdb-selected-frame))))
2873 (if (gdb-get-buffer 'gdb-disassembly-buffer) 2915 (if (gdb-get-buffer 'gdb-disassembly-buffer)
2874 (with-current-buffer (gdb-get-buffer 'gdb-disassembly-buffer) 2916 (with-current-buffer (gdb-get-buffer 'gdb-disassembly-buffer)
2875 (setq mode-name (concat "Machine:" gdb-selected-frame)))) 2917 (setq mode-name (concat "Disassembly:" gdb-selected-frame))))
2876 (if gud-overlay-arrow-position 2918 (if gud-overlay-arrow-position
2877 (let ((buffer (marker-buffer gud-overlay-arrow-position)) 2919 (let ((buffer (marker-buffer gud-overlay-arrow-position))
2878 (position (marker-position gud-overlay-arrow-position))) 2920 (position (marker-position gud-overlay-arrow-position)))
2879 (when buffer 2921 (when buffer
2880 (with-current-buffer buffer 2922 (with-current-buffer buffer