aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Dzhus2009-08-04 13:27:21 +0000
committerDmitry Dzhus2009-08-04 13:27:21 +0000
commite70866834ebd63f1647a4395cafb1d50ebd927d3 (patch)
tree20d48346547539558b4039de3d04cd6138e81b60
parenta5c9f54014c3479dfc68475b5a1e71a56e275205 (diff)
downloademacs-e70866834ebd63f1647a4395cafb1d50ebd927d3.tar.gz
emacs-e70866834ebd63f1647a4395cafb1d50ebd927d3.zip
(gdb-add-pending, gdb-pending-p, gdb-delete-pending): Macros to
handle pending triggers. (gdb-threads-mode-map, def-gdb-thread-buffer-command) (def-gdb-thread-buffer-simple-command) (gdb-display-stack-for-thread, gdb-display-locals-for-thread) (gdb-display-registers-for-thread, gdb-frame-stack-for-thread) (gdb-frame-locals-for-thread, gdb-frame-registers-for-thread): New commands which show buffers bound to thread. (gdb-stack-list-locals-regexp): Removed unused regexp.
-rw-r--r--lisp/ChangeLog9
-rw-r--r--lisp/progmodes/gdb-mi.el162
2 files changed, 124 insertions, 47 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index dd15af771b4..078d66bbf29 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -26,6 +26,15 @@
26 (def-gdb-trigger-and-handler): New macro to define trigger-handler 26 (def-gdb-trigger-and-handler): New macro to define trigger-handler
27 pair for GDB buffer. 27 pair for GDB buffer.
28 (gdb-stack-buffer-name): Add thread information. 28 (gdb-stack-buffer-name): Add thread information.
29 (gdb-add-pending, gdb-pending-p, gdb-delete-pending): Macros to
30 handle pending triggers.
31 (gdb-threads-mode-map, def-gdb-thread-buffer-command)
32 (def-gdb-thread-buffer-simple-command)
33 (gdb-display-stack-for-thread, gdb-display-locals-for-thread)
34 (gdb-display-registers-for-thread, gdb-frame-stack-for-thread)
35 (gdb-frame-locals-for-thread, gdb-frame-registers-for-thread): New
36 commands which show buffers bound to thread.
37 (gdb-stack-list-locals-regexp): Removed unused regexp.
29 38
302009-08-04 Michael Albinus <michael.albinus@gmx.de> 392009-08-04 Michael Albinus <michael.albinus@gmx.de>
31 40
diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el
index 48e8e37de46..f0d5664f74c 100644
--- a/lisp/progmodes/gdb-mi.el
+++ b/lisp/progmodes/gdb-mi.el
@@ -191,7 +191,17 @@ Possible values are these symbols:
191 gdb mode sends to gdb on its own behalf.") 191 gdb mode sends to gdb on its own behalf.")
192 192
193(defvar gdb-pending-triggers '() 193(defvar gdb-pending-triggers '()
194 "A list of trigger functions that have run later than their output handlers.") 194 "A list of trigger functions which have not yet been handled.
195
196Elements are either function names or pairs (buffer . function)")
197
198(defmacro gdb-add-pending (item)
199 `(push ,item gdb-pending-triggers))
200(defmacro gdb-pending-p (item)
201 `(member ,item gdb-pending-triggers))
202(defmacro gdb-delete-pending (item)
203 `(setq gdb-pending-triggers
204 (delete ,item gdb-pending-triggers)))
195 205
196(defcustom gdb-debug-log-max 128 206(defcustom gdb-debug-log-max 128
197 "Maximum size of `gdb-debug-log'. If nil, size is unlimited." 207 "Maximum size of `gdb-debug-log'. If nil, size is unlimited."
@@ -724,17 +734,16 @@ With arg, enter name of variable to be watched in the minibuffer."
724 734
725(defun gdb-speedbar-update () 735(defun gdb-speedbar-update ()
726 (when (and (boundp 'speedbar-frame) (frame-live-p speedbar-frame) 736 (when (and (boundp 'speedbar-frame) (frame-live-p speedbar-frame)
727 (not (member 'gdb-speedbar-timer gdb-pending-triggers))) 737 (not (gdb-pending-p 'gdb-speedbar-timer)))
728 ;; Dummy command to update speedbar even when idle. 738 ;; Dummy command to update speedbar even when idle.
729 (gdb-input (list "-environment-pwd" 'gdb-speedbar-timer-fn)) 739 (gdb-input (list "-environment-pwd" 'gdb-speedbar-timer-fn))
730 ;; Keep gdb-pending-triggers non-nil till end. 740 ;; Keep gdb-pending-triggers non-nil till end.
731 (push 'gdb-speedbar-timer gdb-pending-triggers))) 741 (gdb-add-pending 'gdb-speedbar-timer)))
732 742
733(defun gdb-speedbar-timer-fn () 743(defun gdb-speedbar-timer-fn ()
734 (if gdb-speedbar-auto-raise 744 (if gdb-speedbar-auto-raise
735 (raise-frame speedbar-frame)) 745 (raise-frame speedbar-frame))
736 (setq gdb-pending-triggers 746 (gdb-delete-pending 'gdb-speedbar-timer)
737 (delq 'gdb-speedbar-timer gdb-pending-triggers))
738 (speedbar-timer-fn)) 747 (speedbar-timer-fn))
739 748
740(defun gdb-var-evaluate-expression-handler (varnum changed) 749(defun gdb-var-evaluate-expression-handler (varnum changed)
@@ -831,10 +840,10 @@ numchild=\"\\(.+?\\)\".*?,value=\\(\".*?\"\\).*?,type=\"\\(.+?\\)\".*?}")
831 840
832; Uses "-var-update --all-values". Needs GDB 6.4 onwards. 841; Uses "-var-update --all-values". Needs GDB 6.4 onwards.
833(defun gdb-var-update () 842(defun gdb-var-update ()
834 (if (not (member 'gdb-var-update gdb-pending-triggers)) 843 (if (not (gdb-pending-p 'gdb-var-update))
835 (gdb-input 844 (gdb-input
836 (list "-var-update --all-values *" 'gdb-var-update-handler))) 845 (list "-var-update --all-values *" 'gdb-var-update-handler)))
837 (push 'gdb-var-update gdb-pending-triggers)) 846 (gdb-add-pending 'gdb-var-update))
838 847
839(defconst gdb-var-update-regexp 848(defconst gdb-var-update-regexp
840 "{.*?name=\"\\(.*?\\)\".*?,\\(?:value=\\(\".*?\"\\),\\)?.*?\ 849 "{.*?name=\"\\(.*?\\)\".*?,\\(?:value=\\(\".*?\"\\),\\)?.*?\
@@ -859,8 +868,7 @@ in_scope=\"\\(.*?\\)\".*?}")
859 (read (match-string 2)))) 868 (read (match-string 2))))
860 ((string-equal match "invalid") 869 ((string-equal match "invalid")
861 (gdb-var-delete-1 varnum))))))) 870 (gdb-var-delete-1 varnum)))))))
862 (setq gdb-pending-triggers 871 (gdb-delete-pending 'gdb-var-update)
863 (delq 'gdb-var-update gdb-pending-triggers))
864 (gdb-speedbar-update)) 872 (gdb-speedbar-update))
865 873
866(defun gdb-speedbar-expand-node (text token indent) 874(defun gdb-speedbar-expand-node (text token indent)
@@ -916,13 +924,15 @@ INDENT is the current indentation depth."
916 "Get a specific GDB buffer. 924 "Get a specific GDB buffer.
917 925
918In that buffer, `gdb-buffer-type' must be equal to KEY and 926In that buffer, `gdb-buffer-type' must be equal to KEY and
919`gdb-thread-number' (if provided) must be equal to THREAD." 927`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))
920 (catch 'found 931 (catch 'found
921 (dolist (buffer (buffer-list) nil) 932 (dolist (buffer (buffer-list) nil)
922 (with-current-buffer buffer 933 (with-current-buffer buffer
923 (when (and (eq gdb-buffer-type key) 934 (when (and (eq gdb-buffer-type key)
924 (or (not thread) 935 (equal gdb-thread-number thread))
925 (equal gdb-thread-number thread)))
926 (throw 'found buffer)))))) 936 (throw 'found buffer))))))
927 937
928(defun gdb-get-buffer-create (key &optional thread) 938(defun gdb-get-buffer-create (key &optional thread)
@@ -1222,11 +1232,19 @@ static char *magick[] = {
1222 (process-send-string (get-buffer-process gud-comint-buffer) 1232 (process-send-string (get-buffer-process gud-comint-buffer)
1223 (concat (car item) "\n"))) 1233 (concat (car item) "\n")))
1224 1234
1225(defmacro gdb-current-context-command (command) 1235(defun gdb-current-context-command (command)
1226 "Add --thread option to gdb COMMAND. 1236 "Add --thread option to gdb COMMAND.
1227 1237
1228Option value is taken from `gdb-thread-number'." 1238Option value is taken from `gdb-thread-number'."
1229 (concat command " --thread " gdb-thread-number)) 1239 (concat command " --thread " gdb-thread-number))
1240
1241(defun gdb-current-context-buffer-name (name)
1242 "Add thread information and asterisks to string NAME."
1243 (concat "*" name
1244 (if (local-variable-p 'gdb-thread-number)
1245 " (bound to thread "
1246 " (current thread ")
1247 gdb-thread-number ")*"))
1230 1248
1231 1249
1232(defcustom gud-gdb-command-name "gdb -i=mi" 1250(defcustom gud-gdb-command-name "gdb -i=mi"
@@ -1567,13 +1585,13 @@ are not guaranteed."
1567(defmacro def-gdb-auto-update-trigger (trigger-name gdb-command 1585(defmacro def-gdb-auto-update-trigger (trigger-name gdb-command
1568 handler-name) 1586 handler-name)
1569 `(defun ,trigger-name (&optional signal) 1587 `(defun ,trigger-name (&optional signal)
1570 (if (not (member (cons (current-buffer) ',trigger-name) 1588 (if (not (gdb-pending-p
1571 gdb-pending-triggers)) 1589 (cons (current-buffer) ',trigger-name)))
1572 (progn 1590 (progn
1573 (gdb-input 1591 (gdb-input
1574 (list ,gdb-command 1592 (list ,gdb-command
1575 (gdb-bind-function-to-buffer ',handler-name (current-buffer)))) 1593 (gdb-bind-function-to-buffer ',handler-name (current-buffer))))
1576 (push (cons (current-buffer) ',trigger-name) gdb-pending-triggers))))) 1594 (gdb-add-pending (cons (current-buffer) ',trigger-name))))))
1577 1595
1578;; Used by disassembly buffer only, the rest use 1596;; Used by disassembly buffer only, the rest use
1579;; def-gdb-trigger-and-handler 1597;; def-gdb-trigger-and-handler
@@ -1583,9 +1601,7 @@ are not guaranteed."
1583Delete ((current-buffer) . TRIGGER) from `gdb-pending-triggers', 1601Delete ((current-buffer) . TRIGGER) from `gdb-pending-triggers',
1584erase current buffer and evaluate CUSTOM-DEFUN." 1602erase current buffer and evaluate CUSTOM-DEFUN."
1585 `(defun ,handler-name () 1603 `(defun ,handler-name ()
1586 (setq gdb-pending-triggers 1604 (gdb-delete-pending (cons (current-buffer) ',trigger-name))
1587 (delq (cons (current-buffer) ',trigger-name)
1588 gdb-pending-triggers))
1589 (let* ((buffer-read-only nil)) 1605 (let* ((buffer-read-only nil))
1590 (erase-buffer) 1606 (erase-buffer)
1591 (,custom-defun) 1607 (,custom-defun)
@@ -1619,8 +1635,6 @@ HANDLER-NAME handler uses customization of CUSTOM-DEFUN."
1619 'gdb-invalidate-breakpoints) 1635 'gdb-invalidate-breakpoints)
1620 1636
1621(defun gdb-breakpoints-list-handler-custom () 1637(defun gdb-breakpoints-list-handler-custom ()
1622 (setq gdb-pending-triggers (delq 'gdb-invalidate-breakpoints
1623 gdb-pending-triggers))
1624 (let ((breakpoints-list (gdb-get-field 1638 (let ((breakpoints-list (gdb-get-field
1625 (json-partial-output "bkpt" "script") 1639 (json-partial-output "bkpt" "script")
1626 'BreakpointTable 'body))) 1640 'BreakpointTable 'body)))
@@ -1946,6 +1960,12 @@ FILE is a full path."
1946(defvar gdb-threads-mode-map 1960(defvar gdb-threads-mode-map
1947 (let ((map (make-sparse-keymap))) 1961 (let ((map (make-sparse-keymap)))
1948 (define-key map " " 'gdb-select-thread) 1962 (define-key map " " 'gdb-select-thread)
1963 (define-key map "s" 'gdb-display-stack-for-thread)
1964 (define-key map "S" 'gdb-frame-stack-for-thread)
1965 (define-key map "l" 'gdb-display-locals-for-thread)
1966 (define-key map "L" 'gdb-frame-locals-for-thread)
1967 (define-key map "r" 'gdb-display-registers-for-thread)
1968 (define-key map "R" 'gdb-frame-registers-for-thread)
1949 map)) 1969 map))
1950 1970
1951(defvar gdb-breakpoints-header 1971(defvar gdb-breakpoints-header
@@ -2005,19 +2025,69 @@ FILE is a full path."
2005 (set-marker gdb-thread-position (line-beginning-position))) 2025 (set-marker gdb-thread-position (line-beginning-position)))
2006 (newline)))) 2026 (newline))))
2007 2027
2008(defun gdb-select-thread () 2028(defmacro def-gdb-thread-buffer-command (name custom-defun &optional doc)
2009 "Select the thread at current line of threads buffer." 2029 "Define a NAME command which will act upon thread on the current line.
2010 (interactive) 2030
2011 (save-excursion 2031CUSTOM-DEFUN may use locally bound `thread' variable, which will
2012 (beginning-of-line) 2032be the value of 'gdb-thread propery of the current line. If
2013 (let ((thread (get-text-property (point) 'gdb-thread))) 2033'gdb-thread is nil, error is signaled."
2014 (if thread 2034 `(defun ,name ()
2015 (if (string-equal (gdb-get-field thread 'state) "running") 2035 ,(when doc doc)
2016 (error "Cannot select running thread") 2036 (interactive)
2017 (let ((new-id (gdb-get-field thread 'id))) 2037 (save-excursion
2018 (setq gdb-thread-number new-id) 2038 (beginning-of-line)
2019 (gud-basic-call (concat "-thread-select " new-id)))) 2039 (let ((thread (get-text-property (point) 'gdb-thread)))
2020 (error "Not recognized as thread line"))))) 2040 (if thread
2041 ,custom-defun
2042 (error "Not recognized as thread line"))))))
2043
2044(defmacro def-gdb-thread-buffer-simple-command (name buffer-command &optional doc)
2045 "Define a NAME which will call BUFFER-COMMAND with id of thread
2046on the current line."
2047 `(def-gdb-thread-buffer-command ,name
2048 (,buffer-command (gdb-get-field thread 'id))
2049 ,doc))
2050
2051(def-gdb-thread-buffer-command gdb-select-thread
2052 (if (string-equal (gdb-get-field thread 'state) "running")
2053 (error "Cannot select running thread")
2054 (let ((new-id (gdb-get-field thread 'id)))
2055 (setq gdb-thread-number new-id)
2056 (gud-basic-call (concat "-thread-select " new-id))))
2057 "Select the thread at current line of threads buffer.")
2058
2059(def-gdb-thread-simple-buffer-command
2060 gdb-display-stack-for-thread
2061 gdb-display-stack-buffer
2062 "Display stack buffer for the thread at current line.")
2063
2064(def-gdb-thread-simple-buffer-command
2065 gdb-display-locals-for-thread
2066 gdb-display-locals-buffer
2067 "Display locals buffer for the thread at current line.")
2068
2069(def-gdb-thread-simple-buffer-command
2070 gdb-display-registers-for-thread
2071 gdb-display-registers-buffer
2072 "Display registers buffer for the thread at current line.")
2073
2074(def-gdb-thread-simple-buffer-command
2075 gdb-frame-stack-for-thread
2076 gdb-frame-stack-buffer
2077 "Display a new frame with stack buffer for the thread at
2078current line.")
2079
2080(def-gdb-thread-simple-buffer-command
2081 gdb-frame-locals-for-thread
2082 gdb-frame-locals-buffer
2083 "Display a new frame with locals buffer for the thread at
2084current line.")
2085
2086(def-gdb-thread-simple-buffer-command
2087 gdb-frame-registers-for-thread
2088 gdb-frame-registers-buffer
2089 "Display a new frame with registers buffer for the thread at
2090current line.")
2021 2091
2022 2092
2023;;; Memory view 2093;;; Memory view
@@ -2654,7 +2724,8 @@ member."
2654 (forward-line 1))))) 2724 (forward-line 1)))))
2655 2725
2656(defun gdb-stack-buffer-name () 2726(defun gdb-stack-buffer-name ()
2657 (concat "*stack frames of " (gdb-get-target-string) " (thread " gdb-thread-number ")*")) 2727 (gdb-current-context-buffer-name
2728 (concat "stack frames of " (gdb-get-target-string))))
2658 2729
2659(def-gdb-display-buffer 2730(def-gdb-display-buffer
2660 gdb-display-stack-buffer 2731 gdb-display-stack-buffer
@@ -2724,9 +2795,6 @@ member."
2724 'gdb-locals-mode 2795 'gdb-locals-mode
2725 'gdb-invalidate-locals) 2796 'gdb-invalidate-locals)
2726 2797
2727(defconst gdb-stack-list-locals-regexp
2728 (concat "name=\"\\(.*?\\)\",type=\"\\(.*?\\)\""))
2729
2730(defvar gdb-locals-watch-map 2798(defvar gdb-locals-watch-map
2731 (let ((map (make-sparse-keymap))) 2799 (let ((map (make-sparse-keymap)))
2732 (suppress-keymap map) 2800 (suppress-keymap map)
@@ -2809,7 +2877,8 @@ member."
2809 'gdb-invalidate-locals) 2877 'gdb-invalidate-locals)
2810 2878
2811(defun gdb-locals-buffer-name () 2879(defun gdb-locals-buffer-name ()
2812 (concat "*locals of " (gdb-get-target-string) "*")) 2880 (gdb-current-context-buffer-name
2881 (concat "locals of " (gdb-get-target-string))))
2813 2882
2814(def-gdb-display-buffer 2883(def-gdb-display-buffer
2815 gdb-display-locals-buffer 2884 gdb-display-locals-buffer
@@ -2874,7 +2943,8 @@ member."
2874 'gdb-invalidate-registers) 2943 'gdb-invalidate-registers)
2875 2944
2876(defun gdb-registers-buffer-name () 2945(defun gdb-registers-buffer-name ()
2877 (concat "*registers of " (gdb-get-target-string) "*")) 2946 (gdb-current-context-buffer-name
2947 (concat "registers of " (gdb-get-target-string))))
2878 2948
2879(def-gdb-display-buffer 2949(def-gdb-display-buffer
2880 gdb-display-registers-buffer 2950 gdb-display-registers-buffer
@@ -2889,17 +2959,16 @@ member."
2889;; Needs GDB 6.4 onwards (used to fail with no stack). 2959;; Needs GDB 6.4 onwards (used to fail with no stack).
2890(defun gdb-get-changed-registers () 2960(defun gdb-get-changed-registers ()
2891 (if (and (gdb-get-buffer 'gdb-registers-buffer) 2961 (if (and (gdb-get-buffer 'gdb-registers-buffer)
2892 (not (member 'gdb-get-changed-registers gdb-pending-triggers))) 2962 (not (gdb-pending-p 'gdb-get-changed-registers)))
2893 (progn 2963 (progn
2894 (gdb-input 2964 (gdb-input
2895 (list 2965 (list
2896 "-data-list-changed-registers" 2966 "-data-list-changed-registers"
2897 'gdb-changed-registers-handler)) 2967 'gdb-changed-registers-handler))
2898 (push 'gdb-get-changed-registers gdb-pending-triggers)))) 2968 (gdb-add-pending 'gdb-get-changed-registers))))
2899 2969
2900(defun gdb-changed-registers-handler () 2970(defun gdb-changed-registers-handler ()
2901 (setq gdb-pending-triggers 2971 (gdb-delete-pending 'gdb-get-changed-registers)
2902 (delq 'gdb-get-changed-registers gdb-pending-triggers))
2903 (setq gdb-changed-registers nil) 2972 (setq gdb-changed-registers nil)
2904 (dolist (register-number (gdb-get-field (json-partial-output) 'changed-registers)) 2973 (dolist (register-number (gdb-get-field (json-partial-output) 'changed-registers))
2905 (push register-number gdb-changed-registers))) 2974 (push register-number gdb-changed-registers)))
@@ -2928,7 +2997,7 @@ is set in them."
2928 (propertize "ready" 'face font-lock-variable-name-face))) 2997 (propertize "ready" 'face font-lock-variable-name-face)))
2929 2998
2930(defun gdb-get-selected-frame () 2999(defun gdb-get-selected-frame ()
2931 (if (not (member 'gdb-get-selected-frame gdb-pending-triggers)) 3000 (if (not (gdb-pending-p 'gdb-get-selected-frame))
2932 (progn 3001 (progn
2933 (gdb-input 3002 (gdb-input
2934 (list (gdb-current-context-command "-stack-info-frame") 'gdb-frame-handler)) 3003 (list (gdb-current-context-command "-stack-info-frame") 'gdb-frame-handler))
@@ -2936,8 +3005,7 @@ is set in them."
2936 gdb-pending-triggers)))) 3005 gdb-pending-triggers))))
2937 3006
2938(defun gdb-frame-handler () 3007(defun gdb-frame-handler ()
2939 (setq gdb-pending-triggers 3008 (gdb-delete-pending 'gdb-get-selected-frame)
2940 (delq 'gdb-get-selected-frame gdb-pending-triggers))
2941 (let ((frame (gdb-get-field (json-partial-output) 'frame))) 3009 (let ((frame (gdb-get-field (json-partial-output) 'frame)))
2942 (when frame 3010 (when frame
2943 (setq gdb-frame-number (gdb-get-field frame 'level)) 3011 (setq gdb-frame-number (gdb-get-field frame 'level))