From: "Gerd Möllmann" <gerd.moellmann@gmail.com>
To: "Mattias Engdegård" <mattias.engdegard@gmail.com>
Cc: 66575@debbugs.gnu.org
Subject: bug#66575: [PATCH] Gud lldb support
Date: Tue, 17 Oct 2023 10:15:58 +0200 [thread overview]
Message-ID: <m2sf693br5.fsf@Mini.fritz.box> (raw)
In-Reply-To: <7F2D50C0-FE09-424A-80DB-5F377F3B18A3@gmail.com> ("Mattias Engdegård"'s message of "Mon, 16 Oct 2023 16:46:57 +0200")
[-- Attachment #1: Type: text/plain, Size: 708 bytes --]
Mattias Engdegård <mattias.engdegard@gmail.com> writes:
>> You probably want to include 'lldb' in more places in gud.el. For example:
>>
>>> (defgroup gud nil
>>> "The \"Grand Unified Debugger\" interface.
>>> Supported debuggers include gdb, sdb, dbx, xdb, perldb,
>>> pdb (Python), and jdb."
>>
>> and in gud-text-menu-bar-map, gud-menu-map, etc.
>
> And gud-tooltip-print-command, and probably more places.
Thanks.
Please find a "final" patch attached. This includes NEWS, manual, what
you mentioned and some other stuff. I can't imagine that gud tooltips
for non-gdbmi have worked in the last decade or so... Fortunately, I
don't have a system where I could test that :-).
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: "final" patch --]
[-- Type: text/x-patch, Size: 15467 bytes --]
From d32d5b85c48a05e886224a7b20fab8846ad5c78f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Gerd=20M=C3=B6llmann?= <gerd.moellmann@gmail.com>
Date: Mon, 16 Oct 2023 13:54:02 +0200
Subject: [PATCH] Gud lldb support (bug#66575)
* lisp/progmodes/gud.el (lldb): New command.
* etc/NEWS: Mention M-x lldb.
* src/.lldbinit: Show no souece lines on stop.
* doc/building.texi: Mention LLDB.
---
doc/emacs/building.texi | 6 +-
etc/NEWS | 9 ++
lisp/progmodes/gud.el | 195 +++++++++++++++++++++++++++++++++++-----
src/.lldbinit | 4 +
4 files changed, 189 insertions(+), 25 deletions(-)
diff --git a/doc/emacs/building.texi b/doc/emacs/building.texi
index 2a98bffdc2d..a2639ce6d3e 100644
--- a/doc/emacs/building.texi
+++ b/doc/emacs/building.texi
@@ -567,7 +567,7 @@ Debuggers
The GUD (Grand Unified Debugger) library provides an Emacs interface
to a wide variety of symbolic debuggers. It can run the GNU Debugger
-(GDB), as well as DBX, SDB, XDB, Guile REPL debug commands, Perl's
+(GDB), as well as LLDB, DBX, SDB, XDB, Guile REPL debug commands, Perl's
debugging mode, the Python debugger PDB, and the Java Debugger JDB.
Emacs provides a special interface to GDB, which uses extra Emacs
@@ -609,6 +609,10 @@ Starting GUD
The other commands in this list do the same, for other debugger
programs.
+@item M-x lldb
+@findex lldb
+Run the LLDB debugger.
+
@item M-x perldb
@findex perldb
Run the Perl interpreter in debug mode.
diff --git a/etc/NEWS b/etc/NEWS
index 3bd47a0112b..2111f8daba4 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -197,6 +197,15 @@ displayed on the mode line when 'appt-display-mode-line' is non-nil.
\f
* Editing Changes in Emacs 30.1
++++
+** New command 'lldb'.
+Run the LLDB debugger, analogous to the 'gud-gdb' command. Note that
+might want to add these settings to your .lldbinit file, to reduce the
+output in the LLDB output when stepping through source files.
+
+settings set stop-line-count-before 0
+settings set stop-line-count-after 0
+
+++
** New user option 'gud-highlight-current-line'.
When enabled, Gud will visually emphasize the line being executed upon
diff --git a/lisp/progmodes/gud.el b/lisp/progmodes/gud.el
index d4b954a7203..526a7e5c2ac 100644
--- a/lisp/progmodes/gud.el
+++ b/lisp/progmodes/gud.el
@@ -80,7 +80,7 @@ hl-line-sticky-flag
(defgroup gud nil
"The \"Grand Unified Debugger\" interface.
-Supported debuggers include gdb, sdb, dbx, xdb, perldb,
+Supported debuggers include gdb, lldb, sdb, dbx, xdb, perldb,
pdb (Python), and jdb."
:group 'processes
:group 'tools)
@@ -173,13 +173,13 @@ gud-text-menu-bar-map
"<next>" `(,(propertize "next" 'face 'font-lock-doc-face) . gud-next)
"<until>" `(menu-item
,(propertize "until" 'face 'font-lock-doc-face) gud-until
- :visible (memq gud-minor-mode '(gdbmi gdb perldb)))
+ :visible (memq gud-minor-mode '(gdbmi gdb lldb perldb)))
"<cont>" `(menu-item
,(propertize "cont" 'face 'font-lock-doc-face) gud-cont
:visible (not (eq gud-minor-mode 'gdbmi)))
"<run>" `(menu-item
,(propertize "run" 'face 'font-lock-doc-face) gud-run
- :visible (memq gud-minor-mode '(gdbmi gdb dbx jdb)))
+ :visible (memq gud-minor-mode '(gdbmi gdb lldb dbx jdb)))
"<go>" `(menu-bar-item
,(propertize " go " 'face 'font-lock-doc-face) gud-go
:visible (and (eq gud-minor-mode 'gdbmi)
@@ -231,13 +231,13 @@ gud-menu-map
:enable (not gud-running)]
["Next Instruction" gud-nexti
:enable (not gud-running)
- :visible (memq gud-minor-mode '(gdbmi gdb dbx))]
+ :visible (memq gud-minor-mode '(gdbmi gdb lldb dbx))]
["Step Instruction" gud-stepi
:enable (not gud-running)
- :visible (memq gud-minor-mode '(gdbmi gdb dbx))]
+ :visible (memq gud-minor-mode '(gdbmi gdb lldb dbx))]
["Finish Function" gud-finish
:enable (not gud-running)
- :visible (memq gud-minor-mode '(gdbmi gdb guiler xdb jdb pdb))]
+ :visible (memq gud-minor-mode '(gdbmi gdb lldb guiler xdb jdb pdb))]
["Watch Expression" gud-watch
:enable (not gud-running)
:visible (eq gud-minor-mode 'gdbmi)]
@@ -248,7 +248,7 @@ gud-menu-map
"Dump object"
"Print Dereference")
:enable (not gud-running)
- :visible (memq gud-minor-mode '(gdbmi gdb jdb))]
+ :visible (memq gud-minor-mode '(gdbmi gdb lldb jdb))]
["Print S-expression" gud-pp
:enable (and (not gud-running)
(bound-and-true-p gdb-active-process))
@@ -259,23 +259,23 @@ gud-menu-map
(eq gud-minor-mode 'gdbmi))]
["Down Stack" gud-down
:enable (not gud-running)
- :visible (memq gud-minor-mode '(gdbmi gdb guiler dbx xdb jdb pdb))]
+ :visible (memq gud-minor-mode '(gdbmi gdb lldb guiler dbx xdb jdb pdb))]
["Up Stack" gud-up
:enable (not gud-running)
:visible (memq gud-minor-mode
- '(gdbmi gdb guiler dbx xdb jdb pdb))]
+ '(gdbmi gdb lldb guiler dbx xdb jdb pdb))]
["Set Breakpoint" gud-break
:enable (or (not gud-running) gud-async-running)
:visible (gud-tool-bar-item-visible-no-fringe)]
["Temporary Breakpoint" gud-tbreak
:enable (or (not gud-running) gud-async-running)
- :visible (memq gud-minor-mode '(gdbmi gdb sdb xdb))]
+ :visible (memq gud-minor-mode '(gdbmi gdb lldb sdb xdb))]
["Remove Breakpoint" gud-remove
:enable (or (not gud-running) gud-async-running)
:visible (gud-tool-bar-item-visible-no-fringe)]
["Continue to selection" gud-until
:enable (not gud-running)
- :visible (and (memq gud-minor-mode '(gdbmi gdb perldb))
+ :visible (and (memq gud-minor-mode '(gdbmi gdb lldb perldb))
(gud-tool-bar-item-visible-no-fringe))]
["Stop" gud-stop-subjob
:visible (or (not (memq gud-minor-mode '(gdbmi pdb)))
@@ -288,7 +288,7 @@ gud-menu-map
(gdb-show-run-p))]
["Run" gud-run
:enable (or (not gud-running) gud-async-running)
- :visible (or (memq gud-minor-mode '(gdb dbx jdb))
+ :visible (or (memq gud-minor-mode '(gdb lldb dbx jdb))
(and (eq gud-minor-mode 'gdbmi)
(or (not (gdb-show-run-p))
(bound-and-true-p
@@ -299,7 +299,7 @@ gud-menu-map
(display-graphic-p)
(fboundp 'x-show-tip))
:visible (memq gud-minor-mode
- '(gdbmi guiler dbx sdb xdb pdb))
+ '(gdbmi lldb guiler dbx sdb xdb pdb))
:button (:toggle . gud-tooltip-mode)]
["Info (debugger)" gud-goto-info]))
@@ -973,6 +973,7 @@ gud-gdb-fetch-lines-filter
(setq gud-gdb-fetch-lines-string string)
"")))
+\f
;; gdb speedbar functions
;; Part of the macro expansion of dframe-with-attached-buffer.
@@ -2702,10 +2703,12 @@ gud-delete-prompt-marker
(define-derived-mode gud-mode comint-mode "Debugger"
"Major mode for interacting with an inferior debugger process.
- You start it up with one of the commands \\[gdb], \\[sdb], \\[dbx],
-\\[perldb], \\[xdb], or \\[jdb]. Each entry point finishes by executing a
-hook; `gdb-mode-hook', `sdb-mode-hook', `dbx-mode-hook',
-`perldb-mode-hook', `xdb-mode-hook', or `jdb-mode-hook' respectively.
+ You start it up with one of the commands \\[gdb], \\[lldb],
+\\[sdb], \\[dbx], \\[perldb], \\[xdb], or \\[jdb]. Each entry
+point finishes by executing a hook; `gdb-mode-hook',
+`lldb-mode-hook' `sdb-mode-hook', `dbx-mode-hook',
+`perldb-mode-hook', `xdb-mode-hook', or `jdb-mode-hook'
+respectively.
After startup, the following commands are available in both the GUD
interaction buffer and any source buffer GUD visits due to a breakpoint stop
@@ -2735,11 +2738,11 @@ gud-mode
except that the breakpoint is temporary; that is, it is removed when
execution stops on it.
-Under gdb, dbx, and xdb, \\[gud-up] pops up through an enclosing stack
-frame. \\[gud-down] drops back down through one.
+Under gdb, lldb, dbx, and xdb, \\[gud-up] pops up through an
+enclosing stack frame. \\[gud-down] drops back down through one.
-If you are using gdb or xdb, \\[gud-finish] runs execution to the return from
-the current function and stops.
+If you are using gdb, lldb, or xdb, \\[gud-finish] runs execution
+to the return from the current function and stops.
All the keystrokes above are accessible in the GUD buffer
with the prefix C-c, and in all buffers through the prefix C-x C-a.
@@ -3767,13 +3770,18 @@ gud-tooltip-dereference
; gdb-mi.el gets around this problem.
(defun gud-tooltip-process-output (process output)
"Process debugger output and show it in a tooltip window."
- (remove-function (process-filter process) #'gud-tooltip-process-output)
- (tooltip-show (tooltip-strip-prompt process output)
- (or gud-tooltip-echo-area (not tooltip-mode))))
+ ;; First line is the print command itself.
+ (unless (string-match (regexp-quote (gud-tooltip-print-command ""))
+ output)
+ (remove-function (process-filter process)
+ #'gud-tooltip-process-output)
+ (tooltip-show (tooltip-strip-prompt process output)
+ (or gud-tooltip-echo-area (not tooltip-mode)))))
(defun gud-tooltip-print-command (expr)
"Return a suitable command to print the expression EXPR."
(pcase gud-minor-mode
+ ('lldb (format "dwim-print -- %s" expr))
('gdbmi (concat "-data-evaluate-expression \"" expr "\""))
('guiler expr)
('dbx (concat "print " expr))
@@ -3835,11 +3843,150 @@ gud-tooltip-tips
(gdb-input
(concat cmd "\n")
(lambda () (gdb-tooltip-print expr))))
+ ;; Not gdbmi.
(add-function :override (process-filter process)
#'gud-tooltip-process-output)
(gud-basic-call cmd))
expr))))))))
+\f
+;; 'gud-lldb-history' and 'gud-gud-lldb-command-name' are required
+;; because gud-symbol uses their values if they are present. Their
+;; names are deduced from the minor-mode name.
+(defvar gud-lldb-history nil)
+
+(defcustom gud-gud-lldb-command-name "lldb"
+ "Default command to run an executable under LLDB in text command mode."
+ :type 'string)
+
+(defun gud-lldb-marker-filter (string)
+ "Deduce interesting stuff from output STRING."
+ (cond (;; Process 72668 stopped
+ ;; * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
+ ;; frame #0: ...) at emacs.c:1310:9 [opt]
+ (string-match (rx (and line-start (0+ blank) "frame"
+ (0+ not-newline) " at "
+ (group (1+ (not ":")))
+ ":"
+ (group (1+ digit))))
+ string)
+ (setq gud-last-frame
+ (cons (match-string 1 string)
+ (string-to-number (match-string 2 string)))))
+ (;; Process 72874 exited with status = 9 (0x00000009) killed
+ (string-match (rx "Process " (1+ digit) " exited with status")
+ string)
+ (setq gud-last-last-frame nil)
+ (setq gud-overlay-arrow-position nil)))
+ string)
+
+;;;###autoload
+(defun lldb (command-line)
+ "Run lldb passing it COMMAND-LINE as arguments.
+If COMMAND-LINE names a program FILE to debug, lldb will run in
+a buffer named *gud-FILE*, and the directory containing FILE
+becomes the initial working directory and source-file directory
+for your debugger. If you don't want `default-directory' to
+change to the directory of FILE, specify FILE without leading
+directories, in which case FILE should reside either in the
+directory of the buffer from which this command is invoked, or
+it can be found by searching PATH.
+
+If COMMAND-LINE requests that lldb attaches to a process PID, lldb
+will run in *gud-PID*, otherwise it will run in *gud*; in these
+cases the initial working directory is the `default-directory' of
+the buffer in which this command was invoked."
+ (interactive (list (gud-query-cmdline 'lldb)))
+
+ (when (and gud-comint-buffer
+ (buffer-name gud-comint-buffer)
+ (get-buffer-process gud-comint-buffer)
+ (with-current-buffer gud-comint-buffer (eq gud-minor-mode 'gud-lldb)))
+ (gdb-restore-windows)
+ ;; FIXME: Copied from gud-gdb, but what does that even say?
+ (error "Multiple debugging requires restarting in text command mode"))
+
+ (gud-common-init command-line nil 'gud-lldb-marker-filter)
+ (setq-local gud-minor-mode 'lldb)
+
+ (gud-def gud-break
+ "breakpoint set --joint-specifier %f:%l"
+ "\C-b"
+ "Set breakpoint at current line.")
+ (gud-def gud-tbreak
+ "_regexp-break %f:%l"
+ "\C-t"
+ "Set temporary breakpoint at current line.")
+ (gud-def gud-remove
+ "breakpoint clear --line %l --file %f"
+ "\C-d"
+ "Remove breakpoint at current line")
+ (gud-def gud-step "thread step-in --count %p"
+ "\C-s"
+ "Step one source line with display.")
+ (gud-def gud-stepi
+ "thread step-inst --count %p"
+ "\C-i"
+ "Step one instruction with display.")
+ (gud-def gud-next
+ "thread step-over --count %p"
+ "\C-n"
+ "Step one line (skip functions).")
+ (gud-def gud-nexti
+ "thread step-inst-over --count %p"
+ nil
+ "Step one instruction (skip functions).")
+ (gud-def gud-cont
+ "process continue --ignore-count %p"
+ "\C-r"
+ "Continue with display.")
+ (gud-def gud-finish
+ "thread step-out"
+ "\C-f"
+ "Finish executing current function.")
+ (gud-def gud-jump
+ (progn
+ (gud-call "_regexp-break %f:%l" arg)
+ (gud-call "_regexp-jump %f:%l"))
+ "\C-j"
+ "Set execution address to current line.")
+ (gud-def gud-up
+ "_regexp-up %p"
+ "<"
+ "Up N stack frames (numeric arg).")
+ (gud-def gud-down
+ "_regexp-down %p"
+ ">"
+ "Down N stack frames (numeric arg).")
+ (gud-def gud-print
+ "dwim-print %e"
+ "\C-p"
+ "Evaluate C expression at point.")
+ (gud-def gud-pstar
+ "dwim-print *%e"
+ nil
+ "Evaluate C dereferenced pointer expression at point.")
+ (gud-def gud-pv
+ "xprint %e"
+ "\C-v"
+ "Print value of lisp variable (for debugging Emacs only).")
+ (gud-def gud-until
+ "thread until %l"
+ "\C-u"
+ "Continue to current line.")
+ (gud-def gud-run
+ ;; Extension for process launch --tty?
+ "process launch -X true"
+ nil
+ "Run the program.")
+
+ (gud-set-repeat-map-property 'gud-gdb-repeat-map)
+ (setq comint-prompt-regexp (rx line-start "(lldb)" (0+ blank)))
+ (setq paragraph-start comint-prompt-regexp)
+ (setq gud-running nil)
+ (setq gud-filter-pending-text nil)
+ (run-hooks 'lldb-mode-hook))
+
(provide 'gud)
;;; gud.el ends here
diff --git a/src/.lldbinit b/src/.lldbinit
index a5789f49122..430c48f91f0 100644
--- a/src/.lldbinit
+++ b/src/.lldbinit
@@ -33,4 +33,8 @@ command script import emacs_lldb
# Print with children provider, depth 2.
command alias xprint frame variable -P 2
+# This is for M-x lldb: don't show source lines when stopping.
+settings set stop-line-count-before 0
+settings set stop-line-count-after 0
+
# end.
--
2.42.0
next prev parent reply other threads:[~2023-10-17 8:15 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-16 12:00 bug#66575: [PATCH] Gud lldb support Gerd Möllmann
2023-10-16 13:30 ` Mattias Engdegård
2023-10-16 13:57 ` Mattias Engdegård
2023-10-16 14:46 ` Mattias Engdegård
2023-10-17 8:15 ` Gerd Möllmann [this message]
2023-10-16 14:09 ` Gerd Möllmann
2023-10-17 9:00 ` Mattias Engdegård
2023-10-17 10:03 ` Gerd Möllmann
2023-10-17 11:21 ` Mattias Engdegård
2023-10-17 12:30 ` Gerd Möllmann
2023-10-17 16:18 ` Mattias Engdegård
2023-10-17 16:55 ` Gerd Möllmann
2023-10-17 17:18 ` Gerd Möllmann
2023-10-17 15:40 ` Gerd Möllmann
2023-10-17 16:27 ` Mattias Engdegård
2023-10-17 17:01 ` Gerd Möllmann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=m2sf693br5.fsf@Mini.fritz.box \
--to=gerd.moellmann@gmail.com \
--cc=66575@debbugs.gnu.org \
--cc=mattias.engdegard@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).