aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Dzhus2009-08-04 15:07:23 +0000
committerDmitry Dzhus2009-08-04 15:07:23 +0000
commit4a31122c337fbc0c6242e624d9e26eb13b9cd5e0 (patch)
tree77fbb6982dab49ea54137c8d82719d2308e1a0f1
parent4a6bcbc60243f18091b676b25cdff253515e0baa (diff)
downloademacs-4a31122c337fbc0c6242e624d9e26eb13b9cd5e0.tar.gz
emacs-4a31122c337fbc0c6242e624d9e26eb13b9cd5e0.zip
* progmodes/gud.el (gud-stop-subjob, gud-menu-map): Respect GDB
non-stop settings. * progmodes/gdb-mi.el (gdb-thread-number): Initialize with nil. (gdb-current-context-command): Do not append --thread if `gdb-thread-number' is nil. (gdb-running-threads-count, gdb-stopped-threads-count): New variables. (gdb-non-stop, gdb-gud-control-all-threads, gdb-switch-reasons) (gdb-stopped-hooks, gdb-switch-when-another-stopped): New customization options. (gdb-gud-context-command, gdb-gud-context-call): New wrappers for GUD commands. (gdb): `gud-def' definitions changed to use `gdb-gud-context-call' (gdb-init-1): Activate non-stop mode if `gdb-non-stop' is enabled. (gdb-setq-thread-number, gdb-update-gud-running): New functions to set `gdb-thread-number' and update `gud-running' properly. (gdb-running): Update threads list when new threads appear. (gdb-stopped): Support non-stop operation and new thread switching logic. (gdb-jsonify-buffer, gdb-json-read-buffer, gdb-json-string) (gdb-json-partial-output): New set of JSON routines. (def-gdb-auto-update-trigger): New `signal-list' optional argument. (gdb-thread-list-handler-custom): Update `gud-running', `gdb-stopped-threads-count' and `gdb-running-threads-count'. (def-gdb-thread-buffer-gdb-command, gdb-interrupt-thread) (gdb-continue-thread, gdb-step-thread): New commands for fine thread execution control. (gud-menu-map): New menu items to switch non-stop options. (gdb-reset): Cleanup `gdb-thread-position' overlay arrow marker.
-rw-r--r--lisp/ChangeLog95
-rw-r--r--lisp/progmodes/gdb-mi.el543
-rw-r--r--lisp/progmodes/gud.el48
3 files changed, 520 insertions, 166 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index f7ee7f9b652..cebabd01b14 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,24 +1,52 @@
12009-08-04 Dmitry Dzhus <dima@sphinx.net.ru> 12009-08-04 Dmitry Dzhus <dima@sphinx.net.ru>
2 2
3 * progmodes/gdb-mi.el Basic thread selection support. 3 * progmodes/gud.el (gud-stop-subjob, gud-menu-map): Respect GDB
4 (gdb-thread-number): New variable. 4 non-stop settings.
5 (gdb-current-context-command): New macro which adds --thread 5
6 option to command. 6 * progmodes/gdb-mi.el (gdb-thread-number): Initialize with nil.
7 (gdb-threads-mode-map): Select thread with SPC 7 (gdb-current-context-command): Do not append --thread if
8 (gdb-thread-list-handler-custom): Mark current thread with overlay 8 `gdb-thread-number' is nil.
9 arrow. Synchronize GDB thread and Emacs thread. 9 (gdb-running-threads-count, gdb-stopped-threads-count): New
10 (gdb-select-thread): New command which selects current thread. 10 variables.
11 (gdb-invalidate-frames, gdb-invalidate-locals) 11 (gdb-non-stop, gdb-gud-control-all-threads, gdb-switch-reasons)
12 (gdb-invalidate-registers): Use --thread option. 12 (gdb-stopped-hooks, gdb-switch-when-another-stopped): New
13 (gdb-breakpoints-buffer-name,gdb-locals-buffer-name) 13 customization options.
14 (gdb-registers-buffer-name) 14 (gdb-gud-context-command, gdb-gud-context-call): New wrappers for
15 (gdb-memory-buffer-name, gdb-stack-buffer-name): Do not switch 15 GUD commands.
16 to (gud-comint-buffer) in *-buffer-name functions 16 (gdb): `gud-def' definitions changed to use `gdb-gud-context-call'
17 because (gdb-get-target-string) already does that. 17 (gdb-init-1): Activate non-stop mode if `gdb-non-stop' is enabled.
18 (gdb-locals-handler-custom, gdb-registers-handler-custom) 18 (gdb-setq-thread-number, gdb-update-gud-running): New functions to
19 (gdb-changed-registers-handler): Rewritten without regexps. 19 set `gdb-thread-number' and update `gud-running' properly.
20 (gdb-get-buffer, gdb-get-buffer-create, gdb-init-1) 20 (gdb-running): Update threads list when new threads appear.
21 (gdb-bind-function-to-buffer, gdb-add-subscriber) 21 (gdb-stopped): Support non-stop operation and new thread switching
22 logic.
23 (gdb-jsonify-buffer, gdb-json-read-buffer, gdb-json-string)
24 (gdb-json-partial-output): New set of JSON routines.
25 (def-gdb-auto-update-trigger): New `signal-list' optional
26 argument.
27 (gdb-thread-list-handler-custom): Update `gud-running',
28 `gdb-stopped-threads-count' and `gdb-running-threads-count'.
29 (def-gdb-thread-buffer-gdb-command, gdb-interrupt-thread)
30 (gdb-continue-thread, gdb-step-thread): New commands for fine
31 thread execution control.
32 (gud-menu-map): New menu items to switch non-stop options.
33 (gdb-reset): Cleanup `gdb-thread-position' overlay arrow marker.
34
35 * progmodes/gdb-mi.el (gdb-rules-name-maker)
36 (gdb-rules-buffer-mode, gdb-rules-update-trigger): Accessors for
37 gdb-buffer-rules.
38 (def-gdb-auto-update-handler): New nopreserve optional argument.
39 (gdb-stack-list-frames-custom): Print stack from top to bottom.
40
41 * progmodes/gdb-mi.el (gdb-pc-address): Removed unused variable.
42 (gdb-threads-list, gdb-breakpoints-list): New assoc lists.
43 (gdb-parent-mode): New mode to derive other GDB modes from.
44 (gdb-display-disassembly-for-thread)
45 (gdb-frame-disassembly-for-thread): New commands for threads
46 buffer.
47
48 * progmodes/gdb-mi.el (gdb-get-buffer, gdb-get-buffer-create)
49 (gdb-init-1, gdb-bind-function-to-buffer, gdb-add-subscriber)
22 (gdb-get-subscribers, gdb-emit-signal, gdb-buf-publisher) 50 (gdb-get-subscribers, gdb-emit-signal, gdb-buf-publisher)
23 (gdb-update): We now store all GDB buffers in a list so that they 51 (gdb-update): We now store all GDB buffers in a list so that they
24 can be updated by traversing a list instead of calling invalidate 52 can be updated by traversing a list instead of calling invalidate
@@ -35,16 +63,25 @@
35 (gdb-frame-locals-for-thread, gdb-frame-registers-for-thread): New 63 (gdb-frame-locals-for-thread, gdb-frame-registers-for-thread): New
36 commands which show buffers bound to thread. 64 commands which show buffers bound to thread.
37 (gdb-stack-list-locals-regexp): Removed unused regexp. 65 (gdb-stack-list-locals-regexp): Removed unused regexp.
38 (gdb-pc-address): Removed unused variable. 66
39 (gdb-threads-list, gdb-breakpoints-list): New assoc lists. 67 * progmodes/gdb-mi.el (gdb-breakpoints-buffer-name,gdb-locals-buffer-name)
40 (gdb-parent-mode): New mode to derive other GDB modes from. 68 (gdb-registers-buffer-name)
41 (gdb-display-disassembly-for-thread) 69 (gdb-memory-buffer-name, gdb-stack-buffer-name): Do not switch
42 (gdb-frame-disassembly-for-thread): New commands for threads 70 to (gud-comint-buffer) in *-buffer-name functions
43 buffer. 71 because (gdb-get-target-string) already does that.
44 (gdb-rules-name-maker, gdb-rules-buffer-mode) 72 (gdb-locals-handler-custom, gdb-registers-handler-custom)
45 (gdb-rules-update-trigger): Accessors for gdb-buffer-rules. 73 (gdb-changed-registers-handler): Rewritten without regexps.
46 (def-gdb-auto-update-handler): New nopreserve optional argument. 74
47 (gdb-stack-list-frames-custom): Print stack from top to bottom. 75 * progmodes/gdb-mi.el Basic thread selection support.
76 (gdb-thread-number): New variable.
77 (gdb-current-context-command): New macro which adds --thread
78 option to command.
79 (gdb-threads-mode-map): Select thread with SPC
80 (gdb-thread-list-handler-custom): Mark current thread with overlay
81 arrow. Synchronize GDB thread and Emacs thread.
82 (gdb-select-thread): New command which selects current thread.
83 (gdb-invalidate-frames, gdb-invalidate-locals)
84 (gdb-invalidate-registers): Use --thread option.
48 85
492009-08-04 Michael Albinus <michael.albinus@gmx.de> 862009-08-04 Michael Albinus <michael.albinus@gmx.de>
50 87
diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el
index 1f722264a34..4c3a8531a42 100644
--- a/lisp/progmodes/gdb-mi.el
+++ b/lisp/progmodes/gdb-mi.el
@@ -116,16 +116,18 @@
116 "Address of previous memory page for program memory buffer.") 116 "Address of previous memory page for program memory buffer.")
117 117
118(defvar gdb-frame-number "0") 118(defvar gdb-frame-number "0")
119(defvar gdb-thread-number "1" 119(defvar gdb-thread-number nil
120 "Main current thread. 120 "Main current thread.
121 121
122Invalidation triggers use this variable to query GDB for 122Invalidation triggers use this variable to query GDB for
123information on the specified thread by wrapping GDB/MI commands 123information on the specified thread by wrapping GDB/MI commands
124in `gdb-current-context-command'. 124in `gdb-current-context-command'.
125 125
126This variable may be updated implicitly by GDB via 126This variable may be updated implicitly by GDB via `gdb-stopped'
127`gdb-thread-list-handler-custom' or explicitly by 127or explicitly by `gdb-select-thread'.
128`gdb-select-thread'.") 128
129Only `gdb-setq-thread-number' should be used to change this
130value.")
129 131
130;; Used to show overlay arrow in source buffer. All set in 132;; Used to show overlay arrow in source buffer. All set in
131;; gdb-get-main-selected-frame. Disassembly buffer should not use 133;; gdb-get-main-selected-frame. Disassembly buffer should not use
@@ -141,14 +143,26 @@ This variable may be updated implicitly by GDB via
141 "Associative list of threads provided by \"-thread-info\" MI command. 143 "Associative list of threads provided by \"-thread-info\" MI command.
142 144
143Keys are thread numbers (in strings) and values are structures as 145Keys are thread numbers (in strings) and values are structures as
144returned from -thread-info by `json-partial-output'. Updated in 146returned from -thread-info by `gdb-json-partial-output'. Updated in
145`gdb-thread-list-handler-custom'.") 147`gdb-thread-list-handler-custom'.")
146 148
149(defvar gdb-running-threads-count nil
150 "Number of currently running threads.
151
152Nil means that no information is available.
153
154Updated in `gdb-thread-list-handler-custom'.")
155
156(defvar gdb-stopped-threads-count nil
157 "Number of currently stopped threads.
158
159See also `gdb-running-threads-count'.")
160
147(defvar gdb-breakpoints-list nil 161(defvar gdb-breakpoints-list nil
148 "Associative list of breakpoints provided by \"-break-list\" MI command. 162 "Associative list of breakpoints provided by \"-break-list\" MI command.
149 163
150Keys are breakpoint numbers (in string) and values are structures 164Keys are breakpoint numbers (in string) and values are structures
151as returned from \"-break-list\" by `json-partial-output' 165as returned from \"-break-list\" by `gdb-json-partial-output'
152\(\"body\" field is used). Updated in 166\(\"body\" field is used). Updated in
153`gdb-breakpoints-list-handler-custom'.") 167`gdb-breakpoints-list-handler-custom'.")
154 168
@@ -226,6 +240,85 @@ Elements are either function names or pairs (buffer . function)")
226 (const :tag "Unlimited" nil)) 240 (const :tag "Unlimited" nil))
227 :version "22.1") 241 :version "22.1")
228 242
243(defcustom gdb-non-stop t
244 "When in non-stop mode, stopped threads can be examined while
245other threads continue to execute."
246 :type 'boolean
247 :group 'gdb
248 :version "23.2")
249
250;; TODO Some commands can't be called with --all (give a notice about
251;; it in setting doc)
252(defcustom gdb-gud-control-all-threads t
253 "When enabled, GUD execution commands affect all threads when
254in non-stop mode. Otherwise, only currently selected thread is
255affected."
256 :type 'boolean
257 :group 'gdb
258 :version "23.2")
259
260(defcustom gdb-switch-reasons t
261 "List of stop reasons which cause Emacs to switch to the thread
262which caused the stop. When t, switch to stopped thread no matter
263what the reason was. When nil, never switch to stopped thread
264automatically.
265
266This setting is used in non-stop mode only. In all-stop mode,
267Emacs always switches to the thread which caused the stop."
268 ;; exited, exited-normally and exited-signalled are not
269 ;; thread-specific stop reasons and therefore are not included in
270 ;; this list
271 :type '(choice
272 (const :tag "All reasons" t)
273 (set :tag "Selection of reasons..."
274 (const :tag "A breakpoint was reached." "breakpoint-hit")
275 (const :tag "A watchpoint was triggered." "watchpoint-trigger")
276 (const :tag "A read watchpoint was triggered." "read-watchpoint-trigger")
277 (const :tag "An access watchpoint was triggered." "access-watchpoint-trigger")
278 (const :tag "Function finished execution." "function-finished")
279 (const :tag "Location reached." "location-reached")
280 (const :tag "Watchpoint has gone out of scope" "watchpoint-scope")
281 (const :tag "End of stepping range reached." "end-stepping-range")
282 (const :tag "Signal received (like interruption)." "signal-received"))
283 (const :tag "None" nil))
284 :group 'gdb
285 :version "23.2"
286 :link '(info-link "(gdb)GDB/MI Async Records"))
287
288(defcustom gdb-stopped-hooks nil
289 "This variable holds a list of functions to be called whenever
290GDB stops.
291
292Each function takes one argument, a parsed MI response, which
293contains fields of corresponding MI *stopped async record:
294
295 ((stopped-threads . \"all\")
296 (thread-id . \"1\")
297 (frame (line . \"38\")
298 (fullname . \"/home/sphinx/projects/gsoc/server.c\")
299 (file . \"server.c\")
300 (args ((value . \"0x804b038\")
301 (name . \"arg\")))
302 (func . \"hello\")
303 (addr . \"0x0804869e\"))
304 (reason . \"end-stepping-range\"))
305
306`gdb-get-field' may be used to access the fields of response.
307
308Each function is called after the new current thread was selected
309and GDB buffers were updated in `gdb-stopped'."
310 :type '(repeat function)
311 :group 'gdb
312 :version "23.2"
313 :link '(info-link "(gdb)GDB/MI Async Records"))
314
315(defcustom gdb-switch-when-another-stopped t
316 "When nil, Emacs won't switch to stopped thread if some other
317stopped thread is already selected."
318 :type 'boolean
319 :group 'gdb
320 :version "23.2")
321
229(defvar gdb-debug-log nil 322(defvar gdb-debug-log nil
230 "List of commands sent to and replies received from GDB. 323 "List of commands sent to and replies received from GDB.
231Most recent commands are listed first. This list stores only the last 324Most recent commands are listed first. This list stores only the last
@@ -329,6 +422,29 @@ the list) is deleted every time a new one is added (at the front)."
329 ) 422 )
330 "Font lock keywords used in `gdb-local-mode'.") 423 "Font lock keywords used in `gdb-local-mode'.")
331 424
425;; noall is used for commands which don't take --all, but only
426;; --thread.
427(defun gdb-gud-context-command (command &optional noall)
428 "When `gdb-non-stop' is t, add --thread option to COMMAND if
429`gdb-gud-control-all-threads' is nil and --all option otherwise.
430If NOALL is t, always add --thread option no matter what
431`gdb-gud-control-all-threads' value is.
432
433When `gdb-non-stop' is nil, return COMMAND unchanged."
434 (if gdb-non-stop
435 (if (and gdb-gud-control-all-threads
436 (not noall))
437 (concat command " --all ")
438 (gdb-current-context-command command))
439 command))
440
441;; TODO Document this. We use noarg when not in gud-def
442(defmacro gdb-gud-context-call (cmd1 &optional cmd2 noall noarg)
443 `(gud-call
444 (concat
445 (gdb-gud-context-command ,cmd1 ,noall)
446 ,cmd2) ,(when (not noarg) 'arg)))
447
332;;;###autoload 448;;;###autoload
333(defun gdb (command-line) 449(defun gdb (command-line)
334 "Run gdb on program FILE in buffer *gud-FILE*. 450 "Run gdb on program FILE in buffer *gud-FILE*.
@@ -404,27 +520,28 @@ detailed description of this mode.
404 (gud-def gud-pstar "print* %e" nil 520 (gud-def gud-pstar "print* %e" nil
405 "Evaluate C dereferenced pointer expression at point.") 521 "Evaluate C dereferenced pointer expression at point.")
406 522
407 (gud-def gud-step "-exec-step %p" "\C-s" 523 (gud-def gud-step (gdb-gud-context-call "-exec-step" "%p" t)
524 "\C-s"
408 "Step one source line with display.") 525 "Step one source line with display.")
409 (gud-def gud-stepi "-exec-step-instruction %p" "\C-i" 526 (gud-def gud-stepi (gdb-gud-context-call "-exec-step-instruction" "%p" t)
527 "\C-i"
410 "Step one instruction with display.") 528 "Step one instruction with display.")
411 (gud-def gud-next "-exec-next %p" "\C-n" 529 (gud-def gud-next (gdb-gud-context-call "-exec-next" "%p" t)
530 "\C-n"
412 "Step one line (skip functions).") 531 "Step one line (skip functions).")
413 (gud-def gud-nexti "nexti %p" nil 532 (gud-def gud-nexti (gdb-gud-context-call "-exec-next-instruction" "%p" t)
533 nil
414 "Step one instruction (skip functions).") 534 "Step one instruction (skip functions).")
415 (gud-def gud-cont "-exec-continue" "\C-r" 535 (gud-def gud-cont (gdb-gud-context-call "-exec-continue")
536 "\C-r"
416 "Continue with display.") 537 "Continue with display.")
417 (gud-def gud-finish "-exec-finish" "\C-f" 538 (gud-def gud-finish (gdb-gud-context-call "-exec-finish" nil t)
539 "\C-f"
418 "Finish executing current function.") 540 "Finish executing current function.")
419 (gud-def gud-run "-exec-run" nil "Runn the program.") 541 (gud-def gud-run "-exec-run"
420 542 nil
421 (local-set-key "\C-i" 'gud-gdb-complete-command) 543 "Run the program.")
422 (setq gdb-first-prompt t)
423 (setq gud-running nil)
424 (gdb-update)
425 (run-hooks 'gdb-mode-hook))
426 544
427(defun gdb-init-1 ()
428 (gud-def gud-break (if (not (string-match "Disassembly" mode-name)) 545 (gud-def gud-break (if (not (string-match "Disassembly" mode-name))
429 (gud-call "break %f:%l" arg) 546 (gud-call "break %f:%l" arg)
430 (save-excursion 547 (save-excursion
@@ -432,7 +549,7 @@ detailed description of this mode.
432 (forward-char 2) 549 (forward-char 2)
433 (gud-call "break *%a" arg))) 550 (gud-call "break *%a" arg)))
434 "\C-b" "Set breakpoint at current line or address.") 551 "\C-b" "Set breakpoint at current line or address.")
435 ;; 552
436 (gud-def gud-remove (if (not (string-match "Disassembly" mode-name)) 553 (gud-def gud-remove (if (not (string-match "Disassembly" mode-name))
437 (gud-call "clear %f:%l" arg) 554 (gud-call "clear %f:%l" arg)
438 (save-excursion 555 (save-excursion
@@ -440,7 +557,8 @@ detailed description of this mode.
440 (forward-char 2) 557 (forward-char 2)
441 (gud-call "clear *%a" arg))) 558 (gud-call "clear *%a" arg)))
442 "\C-d" "Remove breakpoint at current line or address.") 559 "\C-d" "Remove breakpoint at current line or address.")
443 ;; 560
561 ;; -exec-until doesn't support --all yet
444 (gud-def gud-until (if (not (string-match "Disassembly" mode-name)) 562 (gud-def gud-until (if (not (string-match "Disassembly" mode-name))
445 (gud-call "-exec-until %f:%l" arg) 563 (gud-call "-exec-until %f:%l" arg)
446 (save-excursion 564 (save-excursion
@@ -448,9 +566,11 @@ detailed description of this mode.
448 (forward-char 2) 566 (forward-char 2)
449 (gud-call "-exec-until *%a" arg))) 567 (gud-call "-exec-until *%a" arg)))
450 "\C-u" "Continue to current line or address.") 568 "\C-u" "Continue to current line or address.")
451 ;; 569 ;; TODO Why arg here?
452 (gud-def 570 (gud-def
453 gud-go (gud-call (if gdb-active-process "-exec-continue" "-exec-run") arg) 571 gud-go (gud-call (if gdb-active-process
572 (gdb-gud-context-command "-exec-continue")
573 "-exec-run") arg)
454 nil "Start or continue execution.") 574 nil "Start or continue execution.")
455 575
456 ;; For debugging Emacs only. 576 ;; For debugging Emacs only.
@@ -488,7 +608,14 @@ detailed description of this mode.
488 'gdb-mouse-jump) 608 'gdb-mouse-jump)
489 (define-key gud-minor-mode-map [left-margin C-mouse-3] 609 (define-key gud-minor-mode-map [left-margin C-mouse-3]
490 'gdb-mouse-jump) 610 'gdb-mouse-jump)
491 ;; 611
612 (local-set-key "\C-i" 'gud-gdb-complete-command)
613 (setq gdb-first-prompt t)
614 (setq gud-running nil)
615 (gdb-update)
616 (run-hooks 'gdb-mode-hook))
617
618(defun gdb-init-1 ()
492 ;; (re-)initialise 619 ;; (re-)initialise
493 (setq gdb-selected-frame nil 620 (setq gdb-selected-frame nil
494 gdb-frame-number nil 621 gdb-frame-number nil
@@ -507,13 +634,15 @@ detailed description of this mode.
507 gdb-debug-log nil 634 gdb-debug-log nil
508 gdb-source-window nil 635 gdb-source-window nil
509 gdb-inferior-status nil 636 gdb-inferior-status nil
510 gdb-continuation nil) 637 gdb-continuation nil
638 gdb-buf-publisher '()
639 gdb-threads-list '()
640 gdb-breakpoints-list '())
511 ;; 641 ;;
512 (setq gdb-buffer-type 'gdbmi) 642 (setq gdb-buffer-type 'gdbmi)
513 ;; 643 ;;
514 (gdb-force-mode-line-update 644 (gdb-force-mode-line-update
515 (propertize "initializing..." 'face font-lock-variable-name-face)) 645 (propertize "initializing..." 'face font-lock-variable-name-face))
516 (setq gdb-buf-publisher '())
517 (when gdb-use-separate-io-buffer 646 (when gdb-use-separate-io-buffer
518 (gdb-get-buffer-create 'gdb-inferior-io) 647 (gdb-get-buffer-create 'gdb-inferior-io)
519 (gdb-clear-inferior-io) 648 (gdb-clear-inferior-io)
@@ -526,6 +655,11 @@ detailed description of this mode.
526 (if (eq window-system 'w32) 655 (if (eq window-system 'w32)
527 (gdb-input (list "-gdb-set new-console off" 'ignore))) 656 (gdb-input (list "-gdb-set new-console off" 'ignore)))
528 (gdb-input (list "-gdb-set height 0" 'ignore)) 657 (gdb-input (list "-gdb-set height 0" 'ignore))
658
659 (when gdb-non-stop
660 (gdb-input (list "-gdb-set non-stop 1" 'ignore))
661 (gdb-input (list "-gdb-set target-async 1" 'ignore)))
662
529 ;; find source file and compilation directory here 663 ;; find source file and compilation directory here
530 (gdb-input 664 (gdb-input
531 ; Needs GDB 6.2 onwards. 665 ; Needs GDB 6.2 onwards.
@@ -944,11 +1078,14 @@ INDENT is the current indentation depth."
944 (assoc gdb-buffer-type gdb-buffer-rules)) 1078 (assoc gdb-buffer-type gdb-buffer-rules))
945 1079
946(defun gdb-current-buffer-thread () 1080(defun gdb-current-buffer-thread ()
947 "Get thread of current buffer from `gdb-threads-list'." 1081 "Get thread object of current buffer from `gdb-threads-list'.
1082
1083When current buffer is not bound to any thread, return main
1084thread."
948 (cdr (assoc gdb-thread-number gdb-threads-list))) 1085 (cdr (assoc gdb-thread-number gdb-threads-list)))
949 1086
950(defun gdb-current-buffer-frame () 1087(defun gdb-current-buffer-frame ()
951 "Get current stack frame for thread of current buffer." 1088 "Get current stack frame object for thread of current buffer."
952 (gdb-get-field (gdb-current-buffer-thread) 'frame)) 1089 (gdb-get-field (gdb-current-buffer-thread) 'frame))
953 1090
954(defun gdb-get-buffer (key &optional thread) 1091(defun gdb-get-buffer (key &optional thread)
@@ -1043,6 +1180,7 @@ DOC is an optional documentation string."
1043 1180
1044(defun gdb-parent-mode () 1181(defun gdb-parent-mode ()
1045 "Generic mode to derive all other GDB buffer modes from." 1182 "Generic mode to derive all other GDB buffer modes from."
1183 (kill-all-local-variables)
1046 (setq buffer-read-only t) 1184 (setq buffer-read-only t)
1047 (buffer-disable-undo) 1185 (buffer-disable-undo)
1048 ;; Delete buffer from gdb-buf-publisher when it's killed 1186 ;; Delete buffer from gdb-buf-publisher when it's killed
@@ -1256,7 +1394,7 @@ static char *magick[] = {
1256 (let ((inhibit-read-only t)) 1394 (let ((inhibit-read-only t))
1257 (remove-text-properties (point-min) (point-max) '(face)))) 1395 (remove-text-properties (point-min) (point-max) '(face))))
1258 ;; mimic <RET> key to repeat previous command in GDB 1396 ;; mimic <RET> key to repeat previous command in GDB
1259 (if (not (string-match "^\\s+$" string)) 1397 (if (not (string= "" string))
1260 (setq gdb-last-command string) 1398 (setq gdb-last-command string)
1261 (if gdb-last-command (setq string gdb-last-command))) 1399 (if gdb-last-command (setq string gdb-last-command)))
1262 (if gdb-enable-debug 1400 (if gdb-enable-debug
@@ -1285,8 +1423,11 @@ static char *magick[] = {
1285(defun gdb-current-context-command (command) 1423(defun gdb-current-context-command (command)
1286 "Add --thread option to gdb COMMAND. 1424 "Add --thread option to gdb COMMAND.
1287 1425
1288Option value is taken from `gdb-thread-number'." 1426Option value is taken from `gdb-thread-number'. If
1289 (concat command " --thread " gdb-thread-number)) 1427`gdb-thread-number' is nil, COMMAND is returned unchanged."
1428 (if gdb-thread-number
1429 (concat command " --thread " gdb-thread-number " ")
1430 command))
1290 1431
1291(defun gdb-current-context-buffer-name (name) 1432(defun gdb-current-context-buffer-name (name)
1292 "Add thread information and asterisks to string NAME." 1433 "Add thread information and asterisks to string NAME."
@@ -1343,15 +1484,15 @@ valid signal handlers.")
1343 (propertize "initializing..." 'face font-lock-variable-name-face)) 1484 (propertize "initializing..." 'face font-lock-variable-name-face))
1344 (gdb-init-1) 1485 (gdb-init-1)
1345 (setq gdb-first-prompt nil)) 1486 (setq gdb-first-prompt nil))
1346 ;; We may need to update gdb-thread-number and gdb-threads-list 1487 ;; We may need to update gdb-threads-list so we can use
1347 (gdb-get-buffer-create 'gdb-threads-buffer) 1488 (gdb-get-buffer-create 'gdb-threads-buffer)
1348 ;; gdb-break-list is maintained in breakpoints handler 1489 ;; gdb-break-list is maintained in breakpoints handler
1349 (gdb-get-buffer-create 'gdb-breakpoints-buffer) 1490 (gdb-get-buffer-create 'gdb-breakpoints-buffer)
1350 1491
1351 (gdb-get-main-selected-frame)
1352
1353 (gdb-emit-signal gdb-buf-publisher 'update) 1492 (gdb-emit-signal gdb-buf-publisher 'update)
1354 1493
1494 (gdb-get-main-selected-frame)
1495
1355 (gdb-get-changed-registers) 1496 (gdb-get-changed-registers)
1356 1497
1357 (when (and (boundp 'speedbar-frame) (frame-live-p speedbar-frame)) 1498 (when (and (boundp 'speedbar-frame) (frame-live-p speedbar-frame))
@@ -1359,6 +1500,28 @@ valid signal handlers.")
1359 (setcar (nthcdr 5 var) nil)) 1500 (setcar (nthcdr 5 var) nil))
1360 (gdb-var-update))) 1501 (gdb-var-update)))
1361 1502
1503;; gdb-setq-thread-number and gdb-update-gud-running are decoupled
1504;; because we may need to update current gud-running value without
1505;; changing current thread (see gdb-running)
1506(defun gdb-setq-thread-number (number)
1507 "Set `gdb-thread-number' to NUMBER and update `gud-running'."
1508 (setq gdb-thread-number number)
1509 (gdb-update-gud-running))
1510
1511(defun gdb-update-gud-running ()
1512 "Set `gud-running' according to the state of current thread.
1513
1514Note that when `gdb-gud-control-all-threads' is t, `gud-running'
1515cannot be reliably used to determine whether or not execution
1516control buttons should be shown in menu or toolbar. Use
1517`gdb-running-threads-count' and `gdb-stopped-threads-count'
1518instead.
1519
1520For all-stop mode, thread information is unavailable while target is running"
1521 (setq gud-running
1522 (string= (gdb-get-field (gdb-current-buffer-thread) 'state)
1523 "running")))
1524
1362;; GUD displays the selected GDB frame. This might might not be the current 1525;; GUD displays the selected GDB frame. This might might not be the current
1363;; GDB frame (after up, down etc). If no GDB frame is visible but the last 1526;; GDB frame (after up, down etc). If no GDB frame is visible but the last
1364;; visited breakpoint is, use that window. 1527;; visited breakpoint is, use that window.
@@ -1385,7 +1548,7 @@ valid signal handlers.")
1385 (gdb-error . "\\([0-9]*\\)\\^error,\\(.*?\\)\n") 1548 (gdb-error . "\\([0-9]*\\)\\^error,\\(.*?\\)\n")
1386 (gdb-console . "~\\(\".*?\"\\)\n") 1549 (gdb-console . "~\\(\".*?\"\\)\n")
1387 (gdb-internals . "&\\(\".*?\"\\)\n") 1550 (gdb-internals . "&\\(\".*?\"\\)\n")
1388 (gdb-stopped . "\\*stopped,?\\(.*?\n\\)") 1551 (gdb-stopped . "\\*stopped,?\\(.*?\\)\n")
1389 (gdb-running . "\\*running,\\(.*?\n\\)") 1552 (gdb-running . "\\*running,\\(.*?\n\\)")
1390 (gdb-thread-created . "=thread-created,\\(.*?\n\\)") 1553 (gdb-thread-created . "=thread-created,\\(.*?\n\\)")
1391 (gdb-thread-exited . "=thread-exited,\\(.*?\n\\)"))) 1554 (gdb-thread-exited . "=thread-exited,\\(.*?\n\\)")))
@@ -1446,15 +1609,20 @@ valid signal handlers.")
1446 gdb-filter-output)) 1609 gdb-filter-output))
1447 1610
1448(defun gdb-gdb (output-field)) 1611(defun gdb-gdb (output-field))
1612
1613;; gdb-invalidate-threads is defined to accept 'update-threads signal
1449(defun gdb-thread-created (output-field)) 1614(defun gdb-thread-created (output-field))
1450(defun gdb-thread-exited (output-field)) 1615(defun gdb-thread-exited (output-field)
1616 (gdb-emit-signal gdb-buf-publisher 'update-threads))
1451 1617
1452(defun gdb-running (output-field) 1618(defun gdb-running (output-field)
1453 (setq gdb-inferior-status "running") 1619 (setq gdb-inferior-status "running")
1454 (gdb-force-mode-line-update 1620 (gdb-force-mode-line-update
1455 (propertize gdb-inferior-status 'face font-lock-type-face)) 1621 (propertize gdb-inferior-status 'face font-lock-type-face))
1622 (when (not gdb-non-stop)
1623 (setq gud-running t))
1456 (setq gdb-active-process t) 1624 (setq gdb-active-process t)
1457 (setq gud-running t)) 1625 (gdb-emit-signal gdb-buf-publisher 'update-threads))
1458 1626
1459(defun gdb-starting (output-field) 1627(defun gdb-starting (output-field)
1460 ;; CLI commands don't emit ^running at the moment so use gdb-running too. 1628 ;; CLI commands don't emit ^running at the moment so use gdb-running too.
@@ -1464,17 +1632,18 @@ valid signal handlers.")
1464 (gdb-force-mode-line-update 1632 (gdb-force-mode-line-update
1465 (propertize gdb-inferior-status 'face font-lock-type-face)) 1633 (propertize gdb-inferior-status 'face font-lock-type-face))
1466 (setq gdb-active-process t) 1634 (setq gdb-active-process t)
1467 (setq gud-running t)) 1635 (when (not gdb-non-stop)
1636 (setq gud-running t)))
1468 1637
1469;; -break-insert -t didn't give a reason before gdb 6.9 1638;; -break-insert -t didn't give a reason before gdb 6.9
1470(defconst gdb-stopped-regexp
1471 "\\(reason=\"\\(.*?\\)\"\\)?\\(\\(,exit-code=.*?\\)*\n\\|.*?,file=\".*?\".*?,fullname=\"\\(.*?\\)\".*?,line=\"\\(.*?\\)\".*?\n\\)")
1472 1639
1473(defun gdb-stopped (output-field) 1640(defun gdb-stopped (output-field)
1474 (setq gud-running nil) 1641 "Given the contents of *stopped MI async record, select new
1475 (string-match gdb-stopped-regexp output-field) 1642current thread and update GDB buffers."
1476 (let ((reason (match-string 2 output-field)) 1643 ;; Reason is available with target-async only
1477 (file (match-string 5 output-field))) 1644 (let* ((result (gdb-json-string output-field))
1645 (reason (gdb-get-field result 'reason))
1646 (thread-id (gdb-get-field result 'thread-id)))
1478 1647
1479;;; Don't set gud-last-frame here as it's currently done in gdb-frame-handler 1648;;; Don't set gud-last-frame here as it's currently done in gdb-frame-handler
1480;;; because synchronous GDB doesn't give these fields with CLI. 1649;;; because synchronous GDB doesn't give these fields with CLI.
@@ -1485,16 +1654,42 @@ valid signal handlers.")
1485;;; (string-to-number 1654;;; (string-to-number
1486;;; (match-string 6 gud-marker-acc))))) 1655;;; (match-string 6 gud-marker-acc)))))
1487 1656
1488 (setq gdb-inferior-status (if reason reason "unknown")) 1657 (setq gdb-inferior-status (or reason "unknown"))
1489 (gdb-force-mode-line-update 1658 (gdb-force-mode-line-update
1490 (propertize gdb-inferior-status 'face font-lock-warning-face)) 1659 (propertize gdb-inferior-status 'face font-lock-warning-face))
1491 (if (string-equal reason "exited-normally") 1660 (if (string-equal reason "exited-normally")
1492 (setq gdb-active-process nil))) 1661 (setq gdb-active-process nil))
1493 1662
1663 ;; Select new current thread.
1664
1665 ;; Don't switch if we have no reasons selected
1666 (when gdb-switch-reasons
1667 ;; Switch from another stopped thread only if we have
1668 ;; gdb-switch-when-another-stopped:
1669 (when (or gdb-switch-when-another-stopped
1670 (not (string= "stopped"
1671 (gdb-get-field (gdb-current-buffer-thread) 'state))))
1672 ;; Switch if current reason has been selected or we have no
1673 ;; reasons
1674 (if (or (eq gdb-switch-reasons t)
1675 (member reason gdb-switch-reasons))
1676 (progn
1677 (gdb-setq-thread-number thread-id)
1678 (message (concat "Switched to thread " thread-id)))
1679 (message (format "Thread %s stopped" thread-id)))))
1680
1681 ;; Print "(gdb)" to GUD console
1494 (when gdb-first-done-or-error 1682 (when gdb-first-done-or-error
1495 (setq gdb-filter-output (concat gdb-filter-output gdb-prompt-name)) 1683 (setq gdb-filter-output (concat gdb-filter-output gdb-prompt-name)))
1684
1685 ;; In non-stop, we update information as soon as another thread gets
1686 ;; stopped
1687 (when (or gdb-first-done-or-error
1688 gdb-non-stop)
1689 ;; In all-stop this updates gud-running properly as well.
1496 (gdb-update) 1690 (gdb-update)
1497 (setq gdb-first-done-or-error nil))) 1691 (setq gdb-first-done-or-error nil))
1692 (run-hook-with-args 'gdb-stopped-hook result)))
1498 1693
1499;; Remove the trimmings from log stream containing debugging messages 1694;; Remove the trimmings from log stream containing debugging messages
1500;; being produced by GDB's internals, use warning face and send to GUD 1695;; being produced by GDB's internals, use warning face and send to GUD
@@ -1571,8 +1766,11 @@ valid signal handlers.")
1571 (with-current-buffer (gdb-get-buffer-create 'gdb-partial-output-buffer) 1766 (with-current-buffer (gdb-get-buffer-create 'gdb-partial-output-buffer)
1572 (erase-buffer))) 1767 (erase-buffer)))
1573 1768
1574(defun json-partial-output (&optional fix-key fix-list) 1769(defun gdb-jsonify-buffer (&optional fix-key fix-list)
1575 "Parse gdb-partial-output-buffer with `json-read'. 1770 "Prepare GDB/MI output in current buffer for parsing with `json-read'.
1771
1772Field names are wrapped in double quotes and equal signs are
1773replaced with semicolons.
1576 1774
1577If FIX-KEY is non-nil, strip all \"FIX-KEY=\" occurences from 1775If FIX-KEY is non-nil, strip all \"FIX-KEY=\" occurences from
1578partial output. This is used to get rid of useless keys in lists 1776partial output. This is used to get rid of useless keys in lists
@@ -1583,20 +1781,17 @@ responses.
1583If FIX-LIST is non-nil, \"FIX-LIST={..}\" is replaced with 1781If FIX-LIST is non-nil, \"FIX-LIST={..}\" is replaced with
1584\"FIX-LIST=[..]\" prior to parsing. This is used to fix broken 1782\"FIX-LIST=[..]\" prior to parsing. This is used to fix broken
1585-break-info output when it contains breakpoint script field 1783-break-info output when it contains breakpoint script field
1586incompatible with GDB/MI output syntax. 1784incompatible with GDB/MI output syntax."
1587 1785 (save-excursion
1588Note that GDB/MI output syntax is different from JSON both
1589cosmetically and (in some cases) structurally, so correct results
1590are not guaranteed."
1591 (with-current-buffer (gdb-get-buffer-create 'gdb-partial-output-buffer)
1592 (goto-char (point-min)) 1786 (goto-char (point-min))
1593 (when fix-key 1787 (when fix-key
1594 (save-excursion 1788 (save-excursion
1595 (while (re-search-forward (concat "[\\[,]\\(" fix-key "=\\)") nil t) 1789 (while (re-search-forward (concat "[\\[,]\\(" fix-key "=\\)") nil t)
1596 (replace-match "" nil nil nil 1)))) 1790 (replace-match "" nil nil nil 1))))
1791 ;; Emacs bug #3794
1597 (when fix-list 1792 (when fix-list
1598 (save-excursion 1793 (save-excursion
1599 ;; Find positions of brackets which enclose broken list 1794 ;; Find positions of braces which enclose broken list
1600 (while (re-search-forward (concat fix-list "={\"") nil t) 1795 (while (re-search-forward (concat fix-list "={\"") nil t)
1601 (let ((p1 (goto-char (- (point) 2))) 1796 (let ((p1 (goto-char (- (point) 2)))
1602 (p2 (progn (forward-sexp) 1797 (p2 (progn (forward-sexp)
@@ -1611,17 +1806,37 @@ are not guaranteed."
1611 (insert "]")))))) 1806 (insert "]"))))))
1612 (goto-char (point-min)) 1807 (goto-char (point-min))
1613 (insert "{") 1808 (insert "{")
1614 ;; Wrap field names in double quotes and replace equal sign with
1615 ;; semicolon.
1616 ;; TODO: This breaks badly with foo= inside constants 1809 ;; TODO: This breaks badly with foo= inside constants
1617 (while (re-search-forward "\\([[:alpha:]-_]+\\)=" nil t) 1810 (while (re-search-forward "\\([[:alpha:]-_]+\\)=" nil t)
1618 (replace-match "\"\\1\":" nil nil)) 1811 (replace-match "\"\\1\":" nil nil))
1619 (goto-char (point-max)) 1812 (goto-char (point-max))
1620 (insert "}") 1813 (insert "}")))
1814
1815(defun gdb-json-read-buffer (&optional fix-key fix-list)
1816 "Prepare and parse GDB/MI output in current buffer with `json-read'.
1817
1818FIX-KEY and FIX-LIST work as in `gdb-jsonify-buffer'."
1819 (gdb-jsonify-buffer fix-key fix-list)
1820 (save-excursion
1621 (goto-char (point-min)) 1821 (goto-char (point-min))
1622 (let ((json-array-type 'list)) 1822 (let ((json-array-type 'list))
1623 (json-read)))) 1823 (json-read))))
1624 1824
1825(defun gdb-json-string (string &optional fix-key fix-list)
1826 "Prepare and parse STRING containing GDB/MI output with `json-read'.
1827
1828FIX-KEY and FIX-LIST work as in `gdb-jsonify-buffer'."
1829 (with-temp-buffer
1830 (insert string)
1831 (gdb-json-read-buffer fix-key fix-list)))
1832
1833(defun gdb-json-partial-output (&optional fix-key fix-list)
1834 "Prepare and parse gdb-partial-output-buffer with `json-read'.
1835
1836FIX-KEY and FIX-KEY work as in `gdb-jsonify-buffer'."
1837 (with-current-buffer (gdb-get-buffer-create 'gdb-partial-output-buffer)
1838 (gdb-json-read-buffer fix-key fix-list)))
1839
1625(defun gdb-pad-string (string padding) 1840(defun gdb-pad-string (string padding)
1626 (format (concat "%" (number-to-string padding) "s") string)) 1841 (format (concat "%" (number-to-string padding) "s") string))
1627 1842
@@ -1634,29 +1849,35 @@ are not guaranteed."
1634 (setq values (append values (list (gdb-get-field struct field))))))) 1849 (setq values (append values (list (gdb-get-field struct field)))))))
1635 1850
1636(defmacro def-gdb-auto-update-trigger (trigger-name gdb-command 1851(defmacro def-gdb-auto-update-trigger (trigger-name gdb-command
1637 handler-name) 1852 handler-name
1853 &optional signal-list)
1638 "Define a trigger TRIGGER-NAME which sends GDB-COMMAND and sets 1854 "Define a trigger TRIGGER-NAME which sends GDB-COMMAND and sets
1639HANDLER-NAME as its handler. HANDLER-NAME is bound to current 1855HANDLER-NAME as its handler. HANDLER-NAME is bound to current
1640buffer with `gdb-bind-function-to-buffer'. 1856buffer with `gdb-bind-function-to-buffer'.
1641 1857
1858If SIGNAL-LIST is non-nil, GDB-COMMAND is sent only when the
1859defined trigger is called with an argument from SIGNAL-LIST.
1860
1642Normally the trigger defined by this command must be called from 1861Normally the trigger defined by this command must be called from
1643the buffer where HANDLER-NAME must work. This should be done so 1862the buffer where HANDLER-NAME must work. This should be done so
1644that buffer-local thread number may be used in GDB-COMMAND (by 1863that buffer-local thread number may be used in GDB-COMMAND (by
1645calling `gdb-current-context-command'). 1864calling `gdb-current-context-command').
1646`gdb-bind-function-to-buffer' is used to achieve this, see how 1865`gdb-bind-function-to-buffer' is used to achieve this, see
1647it's done in `gdb-get-buffer-create'. 1866`gdb-get-buffer-create'.
1648 1867
1649Triggers defined by this command are meant to be used as a 1868Triggers defined by this command are meant to be used as a
1650trigger argument when describing buffer types with 1869trigger argument when describing buffer types with
1651`gdb-set-buffer-rules'." 1870`gdb-set-buffer-rules'."
1652 `(defun ,trigger-name (&optional signal) 1871 `(defun ,trigger-name (&optional signal)
1653 (if (not (gdb-pending-p 1872 (when
1654 (cons (current-buffer) ',trigger-name))) 1873 (or (not ,signal-list)
1655 (progn 1874 (memq signal ,signal-list))
1656 (gdb-input 1875 (when (not (gdb-pending-p
1657 (list ,gdb-command 1876 (cons (current-buffer) ',trigger-name)))
1658 (gdb-bind-function-to-buffer ',handler-name (current-buffer)))) 1877 (gdb-input
1659 (gdb-add-pending (cons (current-buffer) ',trigger-name)))))) 1878 (list ,gdb-command
1879 (gdb-bind-function-to-buffer ',handler-name (current-buffer))))
1880 (gdb-add-pending (cons (current-buffer) ',trigger-name))))))
1660 1881
1661;; Used by disassembly buffer only, the rest use 1882;; Used by disassembly buffer only, the rest use
1662;; def-gdb-trigger-and-handler 1883;; def-gdb-trigger-and-handler
@@ -1665,9 +1886,9 @@ trigger argument when describing buffer types with
1665 1886
1666Handlers are normally called from the buffers they put output in. 1887Handlers are normally called from the buffers they put output in.
1667 1888
1668Delete ((current-buffer) . TRIGGER) from `gdb-pending-triggers', 1889Delete ((current-buffer) . TRIGGER-NAME) from
1669erase current buffer and evaluate CUSTOM-DEFUN. Then 1890`gdb-pending-triggers', erase current buffer and evaluate
1670`gdb-update-buffer-name' is called. 1891CUSTOM-DEFUN. Then `gdb-update-buffer-name' is called.
1671 1892
1672If NOPRESERVE is non-nil, window point is not restored after CUSTOM-DEFUN." 1893If NOPRESERVE is non-nil, window point is not restored after CUSTOM-DEFUN."
1673 `(defun ,handler-name () 1894 `(defun ,handler-name ()
@@ -1684,18 +1905,19 @@ If NOPRESERVE is non-nil, window point is not restored after CUSTOM-DEFUN."
1684 '(set-window-point window p))))) 1905 '(set-window-point window p)))))
1685 1906
1686(defmacro def-gdb-trigger-and-handler (trigger-name gdb-command 1907(defmacro def-gdb-trigger-and-handler (trigger-name gdb-command
1687 handler-name custom-defun) 1908 handler-name custom-defun
1909 &optional signal-list)
1688 "Define trigger and handler. 1910 "Define trigger and handler.
1689 1911
1690TRIGGER-NAME trigger is defined to send GDB-COMMAND. See 1912TRIGGER-NAME trigger is defined to send GDB-COMMAND. See
1691`def-gdb-auto-update-trigger'. 1913`def-gdb-auto-update-trigger'. SIGNAL-LIST determines when
1692 1914
1693HANDLER-NAME handler uses customization of CUSTOM-DEFUN. See 1915HANDLER-NAME handler uses customization of CUSTOM-DEFUN. See
1694`def-gdb-auto-update-handler'." 1916`def-gdb-auto-update-handler'."
1695 `(progn 1917 `(progn
1696 (def-gdb-auto-update-trigger ,trigger-name 1918 (def-gdb-auto-update-trigger ,trigger-name
1697 ,gdb-command 1919 ,gdb-command
1698 ,handler-name) 1920 ,handler-name ,signal-list)
1699 (def-gdb-auto-update-handler ,handler-name 1921 (def-gdb-auto-update-handler ,handler-name
1700 ,trigger-name ,custom-defun))) 1922 ,trigger-name ,custom-defun)))
1701 1923
@@ -1714,7 +1936,7 @@ HANDLER-NAME handler uses customization of CUSTOM-DEFUN. See
1714 1936
1715(defun gdb-breakpoints-list-handler-custom () 1937(defun gdb-breakpoints-list-handler-custom ()
1716 (let ((breakpoints-list (gdb-get-field 1938 (let ((breakpoints-list (gdb-get-field
1717 (json-partial-output "bkpt" "script") 1939 (gdb-json-partial-output "bkpt" "script")
1718 'BreakpointTable 'body))) 1940 'BreakpointTable 'body)))
1719 (setq gdb-breakpoints-list nil) 1941 (setq gdb-breakpoints-list nil)
1720 (insert "Num\tType\t\tDisp\tEnb\tHits\tAddr What\n") 1942 (insert "Num\tType\t\tDisp\tEnb\tHits\tAddr What\n")
@@ -1730,7 +1952,7 @@ HANDLER-NAME handler uses customization of CUSTOM-DEFUN. See
1730 (let ((flag (gdb-get-field breakpoint 'enabled))) 1952 (let ((flag (gdb-get-field breakpoint 'enabled)))
1731 (if (string-equal flag "y") 1953 (if (string-equal flag "y")
1732 (propertize "y" 'face font-lock-warning-face) 1954 (propertize "y" 'face font-lock-warning-face)
1733 (propertize "n" 'face font-lock-type-face))) "\t" 1955 (propertize "n" 'face font-lock-comment-face))) "\t"
1734 (gdb-get-field breakpoint 'times) "\t" 1956 (gdb-get-field breakpoint 'times) "\t"
1735 (gdb-get-field breakpoint 'addr))) 1957 (gdb-get-field breakpoint 'addr)))
1736 (let ((at (gdb-get-field breakpoint 'at))) 1958 (let ((at (gdb-get-field breakpoint 'at)))
@@ -2026,7 +2248,8 @@ FILE is a full path."
2026 2248
2027(def-gdb-trigger-and-handler 2249(def-gdb-trigger-and-handler
2028 gdb-invalidate-threads "-thread-info" 2250 gdb-invalidate-threads "-thread-info"
2029 gdb-thread-list-handler gdb-thread-list-handler-custom) 2251 gdb-thread-list-handler gdb-thread-list-handler-custom
2252 '(update update-threads))
2030 2253
2031(gdb-set-buffer-rules 2254(gdb-set-buffer-rules
2032 'gdb-threads-buffer 2255 'gdb-threads-buffer
@@ -2037,20 +2260,24 @@ FILE is a full path."
2037(defvar gdb-threads-font-lock-keywords 2260(defvar gdb-threads-font-lock-keywords
2038 '(("in \\([^ ]+\\) (" (1 font-lock-function-name-face)) 2261 '(("in \\([^ ]+\\) (" (1 font-lock-function-name-face))
2039 (" \\(stopped\\) in " (1 font-lock-warning-face)) 2262 (" \\(stopped\\) in " (1 font-lock-warning-face))
2263 (" \\(running\\)" (1 font-lock-string-face))
2040 ("\\(\\(\\sw\\|[_.]\\)+\\)=" (1 font-lock-variable-name-face))) 2264 ("\\(\\(\\sw\\|[_.]\\)+\\)=" (1 font-lock-variable-name-face)))
2041 "Font lock keywords used in `gdb-threads-mode'.") 2265 "Font lock keywords used in `gdb-threads-mode'.")
2042 2266
2043(defvar gdb-threads-mode-map 2267(defvar gdb-threads-mode-map
2044 (let ((map (make-sparse-keymap))) 2268 (let ((map (make-sparse-keymap)))
2045 (define-key map "\r" 'gdb-select-thread) 2269 (define-key map "\r" 'gdb-select-thread)
2046 (define-key map "s" 'gdb-display-stack-for-thread) 2270 (define-key map "f" 'gdb-display-stack-for-thread)
2047 (define-key map "S" 'gdb-frame-stack-for-thread) 2271 (define-key map "F" 'gdb-frame-stack-for-thread)
2048 (define-key map "l" 'gdb-display-locals-for-thread) 2272 (define-key map "l" 'gdb-display-locals-for-thread)
2049 (define-key map "L" 'gdb-frame-locals-for-thread) 2273 (define-key map "L" 'gdb-frame-locals-for-thread)
2050 (define-key map "r" 'gdb-display-registers-for-thread) 2274 (define-key map "r" 'gdb-display-registers-for-thread)
2051 (define-key map "R" 'gdb-frame-registers-for-thread) 2275 (define-key map "R" 'gdb-frame-registers-for-thread)
2052 (define-key map "d" 'gdb-display-disassembly-for-thread) 2276 (define-key map "d" 'gdb-display-disassembly-for-thread)
2053 (define-key map "D" 'gdb-frame-disassembly-for-thread) 2277 (define-key map "D" 'gdb-frame-disassembly-for-thread)
2278 (define-key map "i" 'gdb-interrupt-thread)
2279 (define-key map "c" 'gdb-continue-thread)
2280 (define-key map "s" 'gdb-step-thread)
2054 map)) 2281 map))
2055 2282
2056(defvar gdb-breakpoints-header 2283(defvar gdb-breakpoints-header
@@ -2073,45 +2300,52 @@ FILE is a full path."
2073 'gdb-invalidate-threads) 2300 'gdb-invalidate-threads)
2074 2301
2075(defun gdb-thread-list-handler-custom () 2302(defun gdb-thread-list-handler-custom ()
2076 (let* ((res (json-partial-output)) 2303 (let* ((res (gdb-json-partial-output))
2077 (threads-list (gdb-get-field res 'threads)) 2304 (threads-list (gdb-get-field res 'threads)))
2078 (current-thread (gdb-get-field res 'current-thread-id)))
2079 (setq gdb-threads-list nil) 2305 (setq gdb-threads-list nil)
2080 (when (and current-thread 2306 (setq gdb-running-threads-count 0)
2081 (not (string-equal current-thread gdb-thread-number))) 2307 (setq gdb-stopped-threads-count 0)
2082 ;; Implicitly switch thread (in case previous one dies)
2083 (message (concat "GDB switched to another thread: " current-thread))
2084 (setq gdb-thread-number current-thread))
2085 (set-marker gdb-thread-position nil) 2308 (set-marker gdb-thread-position nil)
2086 (dolist (thread threads-list) 2309
2310 (dolist (thread (reverse threads-list))
2311 (let ((running (string-equal (gdb-get-field thread 'state) "running")))
2087 (add-to-list 'gdb-threads-list 2312 (add-to-list 'gdb-threads-list
2088 (cons (gdb-get-field thread 'id) 2313 (cons (gdb-get-field thread 'id)
2089 thread)) 2314 thread))
2090 (insert (apply 'format `("%s (%s) %s in %s " 2315 (if running
2091 ,@(gdb-get-many-fields thread 'id 'target-id 'state) 2316 (incf gdb-running-threads-count)
2092 ,(gdb-get-field thread 'frame 'func)))) 2317 (incf gdb-stopped-threads-count))
2093 ;; Arguments 2318
2094 (insert "(") 2319 (insert (apply 'format `("%s (%s) %s"
2095 (let ((args (gdb-get-field thread 'frame 'args))) 2320 ,@(gdb-get-many-fields thread 'id 'target-id 'state))))
2096 (dolist (arg args) 2321 ;; Include frame information for stopped threads
2097 (insert (apply 'format `("%s=%s" ,@(gdb-get-many-fields arg 'name 'value))))) 2322 (when (not running)
2098 (when args (kill-backward-chars 1))) 2323 (insert (concat " in " (gdb-get-field thread 'frame 'func)))
2099 (insert ")") 2324 (insert " (")
2100 (gdb-insert-frame-location (gdb-get-field thread 'frame)) 2325 (let ((args (gdb-get-field thread 'frame 'args)))
2101 (insert (format " at %s" (gdb-get-field thread 'frame 'addr))) 2326 (dolist (arg args)
2327 (insert (apply 'format `("%s=%s," ,@(gdb-get-many-fields arg 'name 'value)))))
2328 (when args (kill-backward-chars 1)))
2329 (insert ")")
2330 (gdb-insert-frame-location (gdb-get-field thread 'frame))
2331 (insert (format " at %s" (gdb-get-field thread 'frame 'addr))))
2102 (add-text-properties (line-beginning-position) 2332 (add-text-properties (line-beginning-position)
2103 (line-end-position) 2333 (line-end-position)
2104 `(gdb-thread ,thread)) 2334 `(gdb-thread ,thread))
2335 ;; We assume that gdb-thread-number is non-nil by this time
2105 (when (string-equal gdb-thread-number 2336 (when (string-equal gdb-thread-number
2106 (gdb-get-field thread 'id)) 2337 (gdb-get-field thread 'id))
2107 (set-marker gdb-thread-position (line-beginning-position))) 2338 (set-marker gdb-thread-position (line-beginning-position))))
2108 (newline)))) 2339 (newline))
2340 ;; We update gud-running here because we need to make sure that
2341 ;; gdb-threads-list is up-to-date
2342 (gdb-update-gud-running)))
2109 2343
2110(defmacro def-gdb-thread-buffer-command (name custom-defun &optional doc) 2344(defmacro def-gdb-thread-buffer-command (name custom-defun &optional doc)
2111 "Define a NAME command which will act upon thread on the current line. 2345 "Define a NAME command which will act upon thread on the current line.
2112 2346
2113CUSTOM-DEFUN may use locally bound `thread' variable, which will 2347CUSTOM-DEFUN may use locally bound `thread' variable, which will
2114be the value of 'gdb-thread propery of the current line. If 2348be the value of 'gdb-thread property of the current line. If
2115'gdb-thread is nil, error is signaled." 2349'gdb-thread is nil, error is signaled."
2116 `(defun ,name () 2350 `(defun ,name ()
2117 ,(when doc doc) 2351 ,(when doc doc)
@@ -2131,12 +2365,10 @@ on the current line."
2131 ,doc)) 2365 ,doc))
2132 2366
2133(def-gdb-thread-buffer-command gdb-select-thread 2367(def-gdb-thread-buffer-command gdb-select-thread
2134 (if (string-equal (gdb-get-field thread 'state) "running") 2368 (let ((new-id (gdb-get-field thread 'id)))
2135 (error "Cannot select running thread") 2369 (gdb-setq-thread-number new-id)
2136 (let ((new-id (gdb-get-field thread 'id))) 2370 (gdb-input (list (concat "-thread-select " new-id) 'ignore))
2137 (setq gdb-thread-number new-id) 2371 (gdb-update))
2138 (gdb-input (list (concat "-thread-select " new-id) 'ignore))
2139 (gdb-update)))
2140 "Select the thread at current line of threads buffer.") 2372 "Select the thread at current line of threads buffer.")
2141 2373
2142(def-gdb-thread-simple-buffer-command 2374(def-gdb-thread-simple-buffer-command
@@ -2183,6 +2415,34 @@ current line.")
2183 "Display a new frame with disassembly buffer for the thread at 2415 "Display a new frame with disassembly buffer for the thread at
2184current line.") 2416current line.")
2185 2417
2418(defmacro def-gdb-thread-buffer-gdb-command (name gdb-command &optional doc)
2419 "Define a NAME which will execute send GDB-COMMAND with
2420`gdb-thread-number' locally bound to id of thread on the current
2421line."
2422 `(def-gdb-thread-buffer-command ,name
2423 (if gdb-non-stop
2424 (let ((gdb-thread-number (gdb-get-field thread 'id)))
2425 (gdb-input (list (gdb-current-context-command ,gdb-command)
2426 'ignore)))
2427 (error "Available in non-stop mode only, customize gdb-non-stop."))
2428 ,doc))
2429
2430;; Does this make sense in all-stop mode?
2431(def-gdb-thread-buffer-gdb-command
2432 gdb-interrupt-thread
2433 "-exec-interrupt"
2434 "Interrupt thread at current line.")
2435
2436(def-gdb-thread-buffer-gdb-command
2437 gdb-continue-thread
2438 "-exec-continue"
2439 "Continue thread at current line.")
2440
2441(def-gdb-thread-buffer-gdb-command
2442 gdb-step-thread
2443 "-exec-step"
2444 "Step thread at current line.")
2445
2186 2446
2187;;; Memory view 2447;;; Memory view
2188 2448
@@ -2255,7 +2515,7 @@ in `gdb-memory-format'."
2255 (error "Unknown format")))) 2515 (error "Unknown format"))))
2256 2516
2257(defun gdb-read-memory-custom () 2517(defun gdb-read-memory-custom ()
2258 (let* ((res (json-partial-output)) 2518 (let* ((res (gdb-json-partial-output))
2259 (err-msg (gdb-get-field res 'msg))) 2519 (err-msg (gdb-get-field res 'msg)))
2260 (if (not err-msg) 2520 (if (not err-msg)
2261 (let ((memory (gdb-get-field res 'memory))) 2521 (let ((memory (gdb-get-field res 'memory)))
@@ -2635,6 +2895,7 @@ DOC is an optional documentation string."
2635 "Major mode for GDB disassembly information. 2895 "Major mode for GDB disassembly information.
2636 2896
2637\\{gdb-disassembly-mode-map}" 2897\\{gdb-disassembly-mode-map}"
2898 ;; TODO Rename overlay variable for disassembly mode
2638 (add-to-list 'overlay-arrow-variable-list 'gdb-overlay-arrow-position) 2899 (add-to-list 'overlay-arrow-variable-list 'gdb-overlay-arrow-position)
2639 (setq fringes-outside-margins t) 2900 (setq fringes-outside-margins t)
2640 (setq gdb-overlay-arrow-position (make-marker)) 2901 (setq gdb-overlay-arrow-position (make-marker))
@@ -2646,7 +2907,7 @@ DOC is an optional documentation string."
2646(defun gdb-disassembly-handler-custom () 2907(defun gdb-disassembly-handler-custom ()
2647 (let* ((pos 1) 2908 (let* ((pos 1)
2648 (address (gdb-get-field (gdb-current-buffer-frame) 'addr)) 2909 (address (gdb-get-field (gdb-current-buffer-frame) 'addr))
2649 (res (json-partial-output)) 2910 (res (gdb-json-partial-output))
2650 (instructions (gdb-get-field res 'asm_insns)) 2911 (instructions (gdb-get-field res 'asm_insns))
2651 (last-instr (car (last instructions))) 2912 (last-instr (car (last instructions)))
2652 (column-padding (+ 2 (string-width 2913 (column-padding (+ 2 (string-width
@@ -2783,7 +3044,7 @@ member."
2783 (from (insert (format " of %s" from)))))) 3044 (from (insert (format " of %s" from))))))
2784 3045
2785(defun gdb-stack-list-frames-custom () 3046(defun gdb-stack-list-frames-custom ()
2786 (let* ((res (json-partial-output "frame")) 3047 (let* ((res (gdb-json-partial-output "frame"))
2787 (stack (gdb-get-field res 'stack))) 3048 (stack (gdb-get-field res 'stack)))
2788 (dolist (frame stack) 3049 (dolist (frame stack)
2789 (insert (apply 'format `("%s in %s" ,@(gdb-get-many-fields frame 'level 'func)))) 3050 (insert (apply 'format `("%s in %s" ,@(gdb-get-many-fields frame 'level 'func))))
@@ -2904,7 +3165,7 @@ member."
2904;; Dont display values of arrays or structures. 3165;; Dont display values of arrays or structures.
2905;; These can be expanded using gud-watch. 3166;; These can be expanded using gud-watch.
2906(defun gdb-locals-handler-custom () 3167(defun gdb-locals-handler-custom ()
2907 (let ((locals-list (gdb-get-field (json-partial-output) 'locals))) 3168 (let ((locals-list (gdb-get-field (gdb-json-partial-output) 'locals)))
2908 (dolist (local locals-list) 3169 (dolist (local locals-list)
2909 (let ((name (gdb-get-field local 'name)) 3170 (let ((name (gdb-get-field local 'name))
2910 (value (gdb-get-field local 'value)) 3171 (value (gdb-get-field local 'value))
@@ -2981,7 +3242,7 @@ member."
2981 'gdb-invalidate-registers) 3242 'gdb-invalidate-registers)
2982 3243
2983(defun gdb-registers-handler-custom () 3244(defun gdb-registers-handler-custom ()
2984 (let ((register-values (gdb-get-field (json-partial-output) 'register-values)) 3245 (let ((register-values (gdb-get-field (gdb-json-partial-output) 'register-values))
2985 (register-names-list (reverse gdb-register-names))) 3246 (register-names-list (reverse gdb-register-names)))
2986 (dolist (register register-values) 3247 (dolist (register register-values)
2987 (let* ((register-number (gdb-get-field register 'number)) 3248 (let* ((register-number (gdb-get-field register 'number))
@@ -3039,14 +3300,14 @@ member."
3039(defun gdb-changed-registers-handler () 3300(defun gdb-changed-registers-handler ()
3040 (gdb-delete-pending 'gdb-get-changed-registers) 3301 (gdb-delete-pending 'gdb-get-changed-registers)
3041 (setq gdb-changed-registers nil) 3302 (setq gdb-changed-registers nil)
3042 (dolist (register-number (gdb-get-field (json-partial-output) 'changed-registers)) 3303 (dolist (register-number (gdb-get-field (gdb-json-partial-output) 'changed-registers))
3043 (push register-number gdb-changed-registers))) 3304 (push register-number gdb-changed-registers)))
3044 3305
3045(defun gdb-register-names-handler () 3306(defun gdb-register-names-handler ()
3046 ;; Don't use gdb-pending-triggers because this handler is called 3307 ;; Don't use gdb-pending-triggers because this handler is called
3047 ;; only once (in gdb-init-1) 3308 ;; only once (in gdb-init-1)
3048 (setq gdb-register-names nil) 3309 (setq gdb-register-names nil)
3049 (dolist (register-name (gdb-get-field (json-partial-output) 'register-names)) 3310 (dolist (register-name (gdb-get-field (gdb-json-partial-output) 'register-names))
3050 (push register-name gdb-register-names)) 3311 (push register-name gdb-register-names))
3051 (setq gdb-register-names (reverse gdb-register-names))) 3312 (setq gdb-register-names (reverse gdb-register-names)))
3052 3313
@@ -3078,7 +3339,7 @@ thread. Called from `gdb-update'."
3078 "Sets `gdb-pc-address', `gdb-selected-frame' and 3339 "Sets `gdb-pc-address', `gdb-selected-frame' and
3079 `gdb-selected-file' to show overlay arrow in source buffer." 3340 `gdb-selected-file' to show overlay arrow in source buffer."
3080 (gdb-delete-pending 'gdb-get-main-selected-frame) 3341 (gdb-delete-pending 'gdb-get-main-selected-frame)
3081 (let ((frame (gdb-get-field (json-partial-output) 'frame))) 3342 (let ((frame (gdb-get-field (gdb-json-partial-output) 'frame)))
3082 (when frame 3343 (when frame
3083 (setq gdb-frame-number (gdb-get-field frame 'level)) 3344 (setq gdb-frame-number (gdb-get-field frame 'level))
3084 (setq gdb-selected-frame (gdb-get-field frame 'func)) 3345 (setq gdb-selected-frame (gdb-get-field frame 'func))
@@ -3165,9 +3426,8 @@ thread. Called from `gdb-update'."
3165 (define-key menu [breakpoints] 3426 (define-key menu [breakpoints]
3166 '("Breakpoints" . gdb-frame-breakpoints-buffer))) 3427 '("Breakpoints" . gdb-frame-breakpoints-buffer)))
3167 3428
3168(let ((menu (make-sparse-keymap "GDB-MI"))) 3429(let ((menu (make-sparse-keymap "GDB-MI"))
3169 (define-key gud-menu-map [mi] 3430 (submenu (make-sparse-keymap "GUD thread control mode")))
3170 `(menu-item "GDB-MI" ,menu :visible (eq gud-minor-mode 'gdbmi)))
3171 (define-key menu [gdb-customize] 3431 (define-key menu [gdb-customize]
3172 '(menu-item "Customize" (lambda () (interactive) (customize-group 'gdb)) 3432 '(menu-item "Customize" (lambda () (interactive) (customize-group 'gdb))
3173 :help "Customize Gdb Graphical Mode options.")) 3433 :help "Customize Gdb Graphical Mode options."))
@@ -3177,7 +3437,37 @@ thread. Called from `gdb-update'."
3177 :button (:toggle . gdb-many-windows))) 3437 :button (:toggle . gdb-many-windows)))
3178 (define-key menu [gdb-restore-windows] 3438 (define-key menu [gdb-restore-windows]
3179 '(menu-item "Restore Window Layout" gdb-restore-windows 3439 '(menu-item "Restore Window Layout" gdb-restore-windows
3180 :help "Restore standard layout for debug session."))) 3440 :help "Restore standard layout for debug session."))
3441 (define-key menu [sep1]
3442 '(menu-item "--"))
3443 (define-key submenu [all-threads]
3444 '(menu-item "All threads"
3445 (lambda ()
3446 (interactive)
3447 (setq gdb-gud-control-all-threads t))
3448 :help "GUD start/stop commands apply to all threads"
3449 :button (:radio . gdb-gud-control-all-threads)))
3450 (define-key submenu [current-thread]
3451 '(menu-item "Current thread"
3452 (lambda ()
3453 (interactive)
3454 (setq gdb-gud-control-all-threads nil))
3455 :help "GUD start/stop commands apply to current thread only"
3456 :button (:radio . (not gdb-gud-control-all-threads))))
3457 (define-key menu [thread-control]
3458 `("GUD thread control mode" . ,submenu))
3459 (define-key gud-menu-map [mi]
3460 `(menu-item "GDB-MI" ,menu :visible (eq gud-minor-mode 'gdbmi)))
3461 (define-key menu [gdb-switch-when-another-stopped]
3462 (menu-bar-make-toggle gdb-toggle-switch-when-another-stopped gdb-switch-when-another-stopped
3463 "Automatically switch to stopped thread"
3464 "GDB thread switching %s"
3465 "Switch to stopped thread"))
3466 (define-key menu [gdb-non-stop]
3467 (menu-bar-make-toggle gdb-toggle-non-stop gdb-non-stop
3468 "Non-stop mode"
3469 "GDB non-stop mode %s"
3470 "Allow examining stopped threads while others continue to execute")))
3181 3471
3182(defun gdb-frame-gdb-buffer () 3472(defun gdb-frame-gdb-buffer ()
3183 "Display GUD buffer in a new frame." 3473 "Display GUD buffer in a new frame."
@@ -3299,6 +3589,9 @@ Kills the gdb buffers, and resets variables and the source buffers."
3299 (setq gdb-stack-position nil) 3589 (setq gdb-stack-position nil)
3300 (setq overlay-arrow-variable-list 3590 (setq overlay-arrow-variable-list
3301 (delq 'gdb-stack-position overlay-arrow-variable-list)) 3591 (delq 'gdb-stack-position overlay-arrow-variable-list))
3592 (setq gdb-thread-position nil)
3593 (setq overlay-arrow-variable-list
3594 (delq 'gdb-thread-position overlay-arrow-variable-list))
3302 (if (boundp 'speedbar-frame) (speedbar-timer-fn)) 3595 (if (boundp 'speedbar-frame) (speedbar-timer-fn))
3303 (setq gud-running nil) 3596 (setq gud-running nil)
3304 (setq gdb-active-process nil) 3597 (setq gdb-active-process nil)
diff --git a/lisp/progmodes/gud.el b/lisp/progmodes/gud.el
index c20f5adeefc..e31ec2b0883 100644
--- a/lisp/progmodes/gud.el
+++ b/lisp/progmodes/gud.el
@@ -136,11 +136,14 @@ Used to grey out relevant toolbar icons.")
136(defun gud-stop-subjob () 136(defun gud-stop-subjob ()
137 (interactive) 137 (interactive)
138 (with-current-buffer gud-comint-buffer 138 (with-current-buffer gud-comint-buffer
139 (if (string-equal gud-target-name "emacs") 139 (cond ((string-equal gud-target-name "emacs")
140 (comint-stop-subjob) 140 (comint-stop-subjob))
141 (if (eq gud-minor-mode 'jdb) 141 ((eq gud-minor-mode 'jdb)
142 (gud-call "suspend") 142 (gud-call "suspend"))
143 (comint-interrupt-subjob))))) 143 ((eq gud-minor-mode 'gdbmi)
144 (gdb-gud-context-call "-exec-interrupt" nil nil t))
145 (t
146 (comint-interrupt-subjob)))))
144 147
145(easy-mmode-defmap gud-menu-map 148(easy-mmode-defmap gud-menu-map
146 '(([help] "Info (debugger)" . gud-goto-info) 149 '(([help] "Info (debugger)" . gud-goto-info)
@@ -156,12 +159,22 @@ Used to grey out relevant toolbar icons.")
156 :enable (not gud-running) 159 :enable (not gud-running)
157 :visible (memq gud-minor-mode '(gdbmi gdb dbx jdb))) 160 :visible (memq gud-minor-mode '(gdbmi gdb dbx jdb)))
158 ([go] menu-item (if gdb-active-process "Continue" "Run") gud-go 161 ([go] menu-item (if gdb-active-process "Continue" "Run") gud-go
159 :visible (and (not gud-running) 162 :visible (and (eq gud-minor-mode 'gdbmi)
160 (eq gud-minor-mode 'gdbmi))) 163 (or (and (or
164 (not gdb-gud-control-all-threads)
165 (not gdb-non-stop))
166 (not gud-running))
167 (and gdb-gud-control-all-threads
168 (> gdb-stopped-threads-count 0)))))
161 ([stop] menu-item "Stop" gud-stop-subjob 169 ([stop] menu-item "Stop" gud-stop-subjob
162 :visible (or (not (memq gud-minor-mode '(gdbmi pdb))) 170 :visible (or (not (memq gud-minor-mode '(gdbmi pdb)))
163 (and gud-running 171 (and (eq gud-minor-mode 'gdbmi)
164 (eq gud-minor-mode 'gdbmi)))) 172 (or (and (or
173 (not gdb-gud-control-all-threads)
174 (not gdb-non-stop))
175 gud-running)
176 (and gdb-gud-control-all-threads
177 (> gdb-running-threads-count 0))))))
165 ([until] menu-item "Continue to selection" gud-until 178 ([until] menu-item "Continue to selection" gud-until
166 :enable (not gud-running) 179 :enable (not gud-running)
167 :visible (and (memq gud-minor-mode '(gdbmi gdb perldb)) 180 :visible (and (memq gud-minor-mode '(gdbmi gdb perldb))
@@ -248,11 +261,22 @@ Used to grey out relevant toolbar icons.")
248 :visible (memq gud-minor-mode '(gdbmi gdb dbx jdb))) 261 :visible (memq gud-minor-mode '(gdbmi gdb dbx jdb)))
249 ([menu-bar go] menu-item 262 ([menu-bar go] menu-item
250 ,(propertize " go " 'face 'font-lock-doc-face) gud-go 263 ,(propertize " go " 'face 'font-lock-doc-face) gud-go
251 :visible (and (not gud-running) 264 :visible (and (eq gud-minor-mode 'gdbmi)
252 (eq gud-minor-mode 'gdbmi))) 265 (or (and (or
266 (not gdb-gud-control-all-threads)
267 (not gdb-non-stop))
268 (not gud-running))
269 (and gdb-gud-control-all-threads
270 (> gdb-stopped-threads-count 0)))))
253 ([menu-bar stop] menu-item 271 ([menu-bar stop] menu-item
254 ,(propertize "stop" 'face 'font-lock-doc-face) gud-stop-subjob 272 ,(propertize "stop" 'face 'font-lock-doc-face) gud-stop-subjob
255 :visible (or gud-running 273 :visible (or (and (eq gud-minor-mode 'gdbmi)
274 (or (and (or
275 (not gdb-gud-control-all-threads)
276 (not gdb-non-stop))
277 gud-running)
278 (and gdb-gud-control-all-threads
279 (> gdb-running-threads-count 0))))
256 (not (eq gud-minor-mode 'gdbmi)))) 280 (not (eq gud-minor-mode 'gdbmi))))
257 ([menu-bar print] 281 ([menu-bar print]
258 . (,(propertize "print" 'face 'font-lock-doc-face) . gud-print)) 282 . (,(propertize "print" 'face 'font-lock-doc-face) . gud-print))