From: "Andrew L. Moore" <slewsys@gmail.com>
To: emacs-devel@gnu.org
Subject: Contributing LLVM.org patches to gud.el
Date: Thu, 5 Feb 2015 02:46:12 -0500 [thread overview]
Message-ID: <B7F1971C-D3FE-484B-87D8-E4D40F4029E3@gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 417 bytes --]
The LLVM source repository includes a patch adding basic lldb support to gud.el. The patch adapted to current gud.el (Github-mirror commit 7e09ef09a479731d01b1ca46e94ddadd73ac98e3) is attached below. Although I’m not affiliated with llvm.org <http://llvm.org/>, I’d be interested to know if and how this might be accepted into the Emacs distribution, RMS’s opinion of LLVM notwithstanding. Thank you!
-AM
[-- Attachment #2.1: Type: text/html, Size: 729 bytes --]
[-- Attachment #2.2: lldb-gud.el.patch --]
[-- Type: application/octet-stream, Size: 13325 bytes --]
diff --git a/lisp/progmodes/gud.el b/lisp/progmodes/gud.el
index 42c5b20..7f2e9c0 100644
--- a/lisp/progmodes/gud.el
+++ b/lisp/progmodes/gud.el
@@ -35,7 +35,7 @@
;; kluge with the gud-xdb-directories hack producing gud-dbx-directories.
;; Derek L. Davies <ddavies@world.std.com> added support for jdb (Java
;; debugger.) Jan Nieuwenhuizen added support for the Guile REPL (Guile
-;; debugger).
+;; debugger). llvm.org added support for lldb.
;;; Code:
@@ -56,7 +56,7 @@
(defgroup gud nil
"The \"Grand Unified Debugger\" interface.
-Supported debuggers include gdb, sdb, dbx, xdb, perldb,
+Supported debuggers include lldb, gdb, sdb, dbx, xdb, perldb,
pdb (Python), and jdb."
:group 'processes
:group 'tools)
@@ -141,12 +141,12 @@ Used to gray out relevant toolbar icons.")
(display-graphic-p)
(fboundp 'x-show-tip))
:visible (memq gud-minor-mode
- '(gdbmi guiler dbx sdb xdb pdb))
+ '(lldb gdbmi guiler dbx sdb xdb pdb))
:button (:toggle . gud-tooltip-mode))
([refresh] "Refresh" . gud-refresh)
([run] menu-item "Run" gud-run
:enable (not gud-running)
- :visible (memq gud-minor-mode '(gdbmi gdb dbx jdb)))
+ :visible (memq gud-minor-mode '(lldb gdbmi gdb dbx jdb)))
([go] menu-item (if (bound-and-true-p gdb-active-process)
"Continue" "Run") gud-go
:visible (and (eq gud-minor-mode 'gdbmi)
@@ -164,18 +164,18 @@ Used to gray out relevant toolbar icons.")
([tbreak] menu-item "Temporary Breakpoint" gud-tbreak
:enable (not gud-running)
:visible (memq gud-minor-mode
- '(gdbmi gdb sdb xdb)))
+ '(lldb gdbmi gdb sdb xdb)))
([break] menu-item "Set Breakpoint" gud-break
:enable (not gud-running)
:visible (gud-tool-bar-item-visible-no-fringe))
([up] menu-item "Up Stack" gud-up
:enable (not gud-running)
:visible (memq gud-minor-mode
- '(gdbmi gdb guiler dbx xdb jdb pdb)))
+ '(lldb gdbmi gdb guiler dbx xdb jdb pdb)))
([down] menu-item "Down Stack" gud-down
:enable (not gud-running)
:visible (memq gud-minor-mode
- '(gdbmi gdb guiler dbx xdb jdb pdb)))
+ '(lldb gdbmi gdb guiler dbx xdb jdb pdb)))
([pp] menu-item "Print S-expression" gud-pp
:enable (and (not gud-running)
(bound-and-true-p gdb-active-process))
@@ -187,7 +187,7 @@ Used to gray out relevant toolbar icons.")
"Dump object"
"Print Dereference") gud-pstar
:enable (not gud-running)
- :visible (memq gud-minor-mode '(gdbmi gdb jdb)))
+ :visible (memq gud-minor-mode '(lldb gdbmi gdb jdb)))
([print] menu-item "Print Expression" gud-print
:enable (not gud-running))
([watch] menu-item "Watch Expression" gud-watch
@@ -196,13 +196,13 @@ Used to gray out relevant toolbar icons.")
([finish] menu-item "Finish Function" gud-finish
:enable (not gud-running)
:visible (memq gud-minor-mode
- '(gdbmi gdb guiler xdb jdb pdb)))
+ '(lldb gdbmi gdb guiler xdb jdb pdb)))
([stepi] menu-item "Step Instruction" gud-stepi
:enable (not gud-running)
- :visible (memq gud-minor-mode '(gdbmi gdb dbx)))
+ :visible (memq gud-minor-mode '(lldb gdbmi gdb dbx)))
([nexti] menu-item "Next Instruction" gud-nexti
:enable (not gud-running)
- :visible (memq gud-minor-mode '(gdbmi gdb dbx)))
+ :visible (memq gud-minor-mode '(lldb gdbmi gdb dbx)))
([step] menu-item "Step Line" gud-step
:enable (not gud-running))
([next] menu-item "Next Line" gud-next
@@ -237,7 +237,7 @@ Used to gray out relevant toolbar icons.")
:visible (not (eq gud-minor-mode 'gdbmi)))
([menu-bar 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 '(lldb gdbmi gdb dbx jdb)))
([menu-bar go] menu-item
,(propertize " go " 'face 'font-lock-doc-face) gud-go
:visible (and (eq gud-minor-mode 'gdbmi)
@@ -356,6 +356,7 @@ are interpreted specially if present. These are:
%l -- Number of current source line.
%e -- Text of the C lvalue or function-call expression surrounding point.
%a -- Text of the hexadecimal address surrounding point.
+ %b -- Text of the most recently created breakpoint id.
%p -- Prefix argument to the command (if any) as a number.
%c -- Fully qualified class name derived from the expression
surrounding point (jdb only).
@@ -964,6 +965,131 @@ SKIP is the number of chars to skip on each line, it defaults to 0."
\f
;; ======================================================================
+;; lldb functions
+
+;; History of argument lists passed to lldb.
+(defvar gud-lldb-history nil)
+
+;; Keeps track of breakpoint created. In the following case, the id is "1".
+;; It is used to implement temporary breakpoint.
+;; (lldb) b main.c:39
+;; breakpoint set --file 'main.c' --line 39
+;; Breakpoint created: 1: file ='main.c', line = 39, locations = 1
+(defvar gud-breakpoint-id nil)
+
+(defun lldb-extract-breakpoint-id (string)
+ ;; Search for "Breakpoint created: \\([^:\n]*\\):" pattern.
+ (if (string-match "Breakpoint created: \\([^:\n]*\\):" string)
+ (progn
+ (setq gud-breakpoint-id (match-string 1 string))
+ (message "breakpoint id: %s" gud-breakpoint-id)))
+)
+
+(defun gud-lldb-marker-filter (string)
+ (setq gud-marker-acc
+ (if gud-marker-acc (concat gud-marker-acc string) string))
+ (lldb-extract-breakpoint-id gud-marker-acc)
+ (let (start)
+ ;; Process all complete markers in this chunk
+ (while (or
+ ;; (lldb) r
+ ;; Process 15408 launched: '/Volumes/data/lldb/svn/trunk/test/conditional_break/a.out' (x86_64)
+ ;; (lldb) Process 15408 stopped
+ ;; * thread #1: tid = 0x2e03, 0x0000000100000de8 a.out`c + 7 at main.c:39, stop reason = breakpoint 1.1, queue = com.apple.main-thread
+ (string-match " at \\([^:\n]*\\):\\([0-9]*\\), stop reason = .*\n"
+ gud-marker-acc start)
+ ;; (lldb) frame select -r 1
+ ;; frame #1: 0x0000000100000e09 a.out`main + 25 at main.c:44
+ (string-match "\nframe.* at \\([^:\n]*\\):\\([0-9]*\\)\n"
+ gud-marker-acc start))
+ (setq gud-last-frame
+ (cons (match-string 1 gud-marker-acc)
+ (string-to-number (match-string 2 gud-marker-acc)))
+ start (match-end 0)))
+
+ ;; Search for the last incomplete line in this chunk
+ (while (string-match "\n" gud-marker-acc start)
+ (setq start (match-end 0)))
+
+ ;; If we have an incomplete line, store it in gud-marker-acc.
+ (setq gud-marker-acc (substring gud-marker-acc (or start 0))))
+ string)
+
+;; Keeps track of whether the Python lldb_oneshot_break function definition has
+;; been exec'ed.
+(defvar lldb-oneshot-break-defined nil)
+
+;;;###autoload
+(defun lldb (command-line)
+ "Run lldb on program FILE in buffer *gud-FILE*.
+The directory containing FILE becomes the initial working directory
+and source-file directory for your debugger."
+ (interactive (list (gud-query-cmdline 'lldb)))
+
+ (gud-common-init command-line nil 'gud-lldb-marker-filter)
+ (set (make-local-variable 'gud-minor-mode) 'lldb)
+ (setq lldb-oneshot-break-defined nil)
+
+ (gud-def gud-listb "breakpoint list"
+ "l" "List all breakpoints.")
+ (gud-def gud-bt "thread backtrace"
+ "b" "Show stack for the current thread.")
+ (gud-def gud-bt-all "thread backtrace all"
+ "B" "Show stacks for all the threads.")
+
+ (gud-def gud-break "breakpoint set -f %f -l %l"
+ "\C-b" "Set breakpoint at current line.")
+ (gud-def gud-tbreak
+ (progn (gud-call "breakpoint set -f %f -l %l")
+ (sit-for 1)
+ (if (not lldb-oneshot-break-defined)
+ (progn
+ ;; The "\\n"'s are required to escape the newline chars
+ ;; passed to the lldb process.
+ (gud-call (concat "script exec \"def lldb_oneshot_break(frame, bp_loc):\\n"
+ " target=frame.GetThread().GetProcess().GetTarget()\\n"
+ " bp=bp_loc.GetBreakpoint()\\n"
+ " print 'Deleting oneshot breakpoint:', bp\\n"
+ " target.BreakpointDelete(bp.GetID())\""))
+ (sit-for 1)
+ ;; Set the flag since Python knows about the function def now.
+ (setq lldb-oneshot-break-defined t)))
+ (gud-call "breakpoint command add -p %b -o 'lldb_oneshot_break(frame, bp_loc)'"))
+ "\C-t" "Set temporary breakpoint at current line.")
+ (gud-def gud-remove "breakpoint clear -f %f -l %l"
+ "\C-d" "Remove breakpoint at current line")
+ (gud-def gud-step "thread step-in"
+ "\C-s" "Step one source line with display.")
+ (gud-def gud-stepi "thread step-inst"
+ "\C-i" "Step one instruction with display.")
+ (gud-def gud-next "thread step-over"
+ "\C-n" "Step one line (skip functions).")
+ (gud-def gud-nexti "thread step-inst-over"
+ nil "Step one instruction (skip functions).")
+ (gud-def gud-cont "process continue"
+ "\C-r" "Continue with display.")
+ (gud-def gud-finish "thread step-out"
+ "\C-f" "Finish executing current function.")
+ (gud-def gud-up "frame select -r %p"
+ "<" "Up 1 stack frame.")
+ (gud-def gud-down "frame select -r -%p"
+ ">" "Down 1 stack frame.")
+ (gud-def gud-print "expression -- %e"
+ "\C-p" "Evaluate C expression at point.")
+ (gud-def gud-pstar "expression -- *%e"
+ nil "Evaluate C dereferenced pointer expression at point.")
+ (gud-def gud-run "run"
+ nil "Run the program.")
+ (gud-def gud-stop-subjob "process kill"
+ nil "Stop the program.")
+
+ (setq comint-prompt-regexp "\\(^\\|\n\\)\\*")
+ (setq paragraph-start comint-prompt-regexp)
+ (run-hooks 'lldb-mode-hook)
+ )
+
+\f
+;; ======================================================================
;; sdb functions
;; History of argument lists passed to sdb.
@@ -2499,9 +2625,10 @@ gud, see `gud-mode'."
"Major mode for interacting with an inferior debugger process.
You start it up with one of the commands M-x gdb, M-x sdb, M-x dbx,
-M-x perldb, M-x xdb, or M-x 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.
+M-x perldb, M-x xdb, M-x jdb, or M-x lldb. Each entry point finishes by
+executing a hook; `gdb-mode-hook', `sdb-mode-hook', `dbx-mode-hook',
+`perldb-mode-hook', `xdb-mode-hook', `jdb-mode-hook', or `lldb-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
@@ -2531,7 +2658,7 @@ Under gdb, sdb and xdb, \\[gud-tbreak] behaves exactly like \\[gud-break],
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
+Under gdb, dbx, xdb, and lldb, \\[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
@@ -2858,7 +2985,7 @@ Obeying it means displaying in another window the specified file and line."
result)
(while (and str
(let ((case-fold-search nil))
- (string-match "\\([^%]*\\)%\\([adefFlpc]\\)" str)))
+ (string-match "\\([^%]*\\)%\\([abdefFlpc]\\)" str)))
(let ((key (string-to-char (match-string 2 str)))
subst)
(cond
@@ -2886,6 +3013,8 @@ Obeying it means displaying in another window the specified file and line."
(setq subst (gud-find-expr)))
((eq key ?a)
(setq subst (gud-read-address)))
+ ((eq key ?b)
+ (setq subst gud-breakpoint-id))
((eq key ?c)
(setq subst
(gud-find-class
@@ -3520,6 +3649,7 @@ With arg, dereference expr if ARG is positive, otherwise do not dereference."
(defun gud-tooltip-print-command (expr)
"Return a suitable command to print the expression EXPR."
(pcase gud-minor-mode
+ (`lldb (concat "expression -o -- \"" expr "\""))
(`gdbmi (concat "-data-evaluate-expression \"" expr "\""))
(`guiler expr)
(`dbx (concat "print " expr))
[-- Attachment #2.3: Type: text/html, Size: 233 bytes --]
next reply other threads:[~2015-02-05 7:46 UTC|newest]
Thread overview: 124+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-02-05 7:46 Andrew L. Moore [this message]
2015-02-05 8:53 ` Contributing LLVM.org patches to gud.el David Kastrup
2015-02-05 14:15 ` Stefan Monnier
2015-02-06 12:41 ` Richard Stallman
2015-02-06 12:49 ` David Kastrup
2015-02-06 18:21 ` Richard Stallman
2015-02-06 19:00 ` Stefan Monnier
2015-02-07 8:46 ` Helmut Eller
2015-02-07 10:18 ` David Kastrup
2015-02-07 11:42 ` Helmut Eller
2015-02-07 11:53 ` David Kastrup
2015-02-09 0:06 ` Richard Stallman
2015-02-09 3:27 ` Stephen J. Turnbull
2015-02-15 22:50 ` Richard Stallman
2015-02-16 5:19 ` Stephen J. Turnbull
2015-02-16 16:23 ` Richard Stallman
2015-02-09 11:21 ` David Kastrup
2015-02-09 14:21 ` Stefan Monnier
2015-02-09 22:07 ` Richard Stallman
2015-02-09 23:59 ` David Kastrup
2015-02-10 2:40 ` Stefan Monnier
2015-02-10 3:52 ` Eli Zaretskii
2015-02-10 8:59 ` David Kastrup
2015-02-10 16:00 ` Eli Zaretskii
2015-02-10 16:41 ` David Kastrup
2015-02-10 16:58 ` Eli Zaretskii
2015-02-11 3:43 ` Stephen J. Turnbull
2015-02-11 3:47 ` Daniel Colascione
2015-02-11 10:37 ` David Kastrup
2015-02-11 10:51 ` Daniel Colascione
2015-02-11 13:22 ` Stephen J. Turnbull
2015-02-11 16:07 ` Eli Zaretskii
2015-02-12 16:26 ` Eli Zaretskii
2015-02-12 17:42 ` Daniel Colascione
2015-02-12 20:15 ` Eli Zaretskii
2015-02-11 15:54 ` Eli Zaretskii
2015-02-11 23:12 ` Richard Stallman
2015-02-11 15:42 ` Eli Zaretskii
2015-02-11 15:41 ` Eli Zaretskii
2015-02-12 4:20 ` Stephen J. Turnbull
2015-02-12 11:23 ` David Kastrup
2015-02-12 13:13 ` Stephen J. Turnbull
2015-02-12 15:52 ` Eli Zaretskii
2015-02-11 4:26 ` Stephen J. Turnbull
2015-02-11 7:44 ` Nicholas Allegra
2015-02-11 15:43 ` Eli Zaretskii
2015-02-11 16:21 ` Stefan Monnier
2015-02-11 16:27 ` David Kastrup
2015-02-11 16:42 ` Eli Zaretskii
2015-02-12 5:41 ` Stephen J. Turnbull
2015-02-12 16:33 ` Eli Zaretskii
2015-02-12 18:29 ` Stephen J. Turnbull
2015-02-12 17:34 ` Richard Stallman
2015-02-10 17:03 ` David Engster
2015-02-10 17:18 ` Eli Zaretskii
2015-02-10 17:36 ` David Engster
2015-02-10 19:15 ` Eli Zaretskii
2015-02-10 20:25 ` David Engster
2015-02-10 22:49 ` Richard Stallman
2015-02-11 10:35 ` David Kastrup
2015-02-11 23:12 ` Richard Stallman
2015-02-10 18:07 ` David Kastrup
2015-02-10 19:21 ` Eli Zaretskii
2015-02-10 20:33 ` Stefan Monnier
2015-02-11 23:08 ` Richard Stallman
2015-02-09 16:08 ` Eli Zaretskii
2015-02-09 22:08 ` Richard Stallman
2015-02-09 20:00 ` Florian Weimer
2015-02-07 14:46 ` Stefan Monnier
2015-02-07 22:40 ` Richard Stallman
2015-02-07 23:04 ` David Kastrup
2015-02-08 0:15 ` Eric S. Raymond
2015-02-08 0:51 ` David Kastrup
2015-02-09 20:04 ` Perry E. Metzger
2015-02-10 22:49 ` Richard Stallman
2015-02-11 16:17 ` Perry E. Metzger
2015-02-11 23:13 ` Richard Stallman
2015-02-11 23:37 ` Perry E. Metzger
2015-02-12 11:22 ` David Kastrup
2015-02-12 14:45 ` Stephen J. Turnbull
2015-02-12 17:34 ` Richard Stallman
2015-02-13 10:11 ` Tom
2015-02-13 10:20 ` Eli Zaretskii
2015-02-13 10:27 ` Tom
2015-02-13 11:00 ` Eli Zaretskii
2015-02-14 15:22 ` Richard Stallman
2015-02-12 11:08 ` David Kastrup
2015-02-14 15:22 ` Richard Stallman
2015-02-11 23:13 ` Richard Stallman
2015-02-12 10:28 ` David Kastrup
2015-02-13 9:25 ` Richard Stallman
2015-02-09 20:13 ` Florian Weimer
2015-02-10 22:49 ` Richard Stallman
2015-02-08 3:55 ` Liang Wang
2015-02-08 9:30 ` David Kastrup
2015-02-09 0:04 ` Richard Stallman
2015-02-09 8:47 ` David Kastrup
2015-02-09 22:07 ` Richard Stallman
2015-02-09 23:03 ` David Kastrup
2015-02-11 23:09 ` Richard Stallman
2015-02-09 16:15 ` Robin Templeton
2015-02-09 20:13 ` Perry E. Metzger
2015-02-09 22:08 ` Richard Stallman
2015-02-10 8:24 ` Helmut Eller
2015-02-10 9:31 ` David Kastrup
2015-02-10 10:44 ` Helmut Eller
2015-02-10 10:53 ` David Kastrup
2015-02-10 12:45 ` Helmut Eller
2015-02-10 13:35 ` David Kastrup
2015-02-10 15:42 ` Yann Hodique
2015-02-10 16:11 ` David Kastrup
2015-02-10 22:49 ` Richard Stallman
2015-02-11 10:20 ` David Kastrup
2015-02-11 15:16 ` Stefan Monnier
2015-02-11 23:13 ` Richard Stallman
2015-02-09 20:06 ` Florian Weimer
2015-02-09 20:34 ` David Kastrup
2015-02-10 22:46 ` Richard Stallman
2015-02-06 19:21 ` David Kastrup
2015-02-07 5:50 ` Stephen J. Turnbull
2015-02-06 14:57 ` Stefan Monnier
2015-02-07 12:44 ` Richard Stallman
2015-02-07 14:48 ` Stefan Monnier
2015-02-07 22:41 ` Richard Stallman
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=B7F1971C-D3FE-484B-87D8-E4D40F4029E3@gmail.com \
--to=slewsys@gmail.com \
--cc=emacs-devel@gnu.org \
/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).