;;;; breakpoints.el - find marked breakpoints in buffers ;;; Ed L. Cashin releases this version of breakpoints.el into ;;; the public domain without any warranties. ;;; ;;; I noticed I was wasting a lot of time setting breakpoints ;;; at specific lines in files I had open in emacs. These ;;; simple lisp routines find those breakpoints, which it ;;; expects to be two lines below an "elc-break:" mark, and ;;; returns a string of gdb commands. ;;; ;;; do "M-x cmds-breakpoints RET" to insert the gdb commands ;;; into the buffer you're visiting. ;;; ;;; You will have to set bkpt-dbg-files to the right locations ;;; for your files. Also, unless you really want to use "elc-break:" ;;; to mark breakpoints in your kernel source, you'll need to set ;;; bkpt-marker-string too. ;;; ;;; Here's one way to load this stuff in your .emacs: ;;; ;;; (let ((f "~/kernel/linux-2.4.18-kgdb/scripts/breakpoints.el")) ;;; (if (file-readable-p f) ;;; (let ((b (substring f 0 -3))) ;;; (message ".emacs: loading linux debugging support library") ;;; (load-library b)))) ;;; (defvar bkpt-dbg-files nil ; '("/home/ecashin/kernel/linux-2.4.18-kgdb/mm/memory.c" ; "/home/ecashin/kernel/linux-2.4.18-kgdb/kernel/fork.c" ; "/home/ecashin/kernel/linux-2.4.18-kgdb/kernel/dclone.c") "the files I wuv to debug") (defvar bkpt-dbg-excluded-files '("/home/ecashin/kernel/linux-2.4.18-kgdb/scripts/breakpoints.el") "the files I don't want to debug") (defvar bkpt-dbg-file-prefixes '("/home/ecashin/kernel/linux-2.4.18-kgdb") "all files with names starting with one of these are to be examined") (defvar bkpt-marker-string "elc-break:" "the string that appears two lines above the breakpoint") ;;; comment this out if not debugging: ;; (setq bkpt-dbg-buffer ;; (get-buffer-create "bkpt-dbg")) (defvar bkpt-dbg-buffer nil "the buffer where debugging info will go (no debugging if nil)") (defun dbgprt (s) (if bkpt-dbg-buffer (with-current-buffer bkpt-dbg-buffer (insert s)))) (require 'cl) ; oh, to do labels without it! (defun bkpt-prefix-match (fname) "tell whether FNAME has a prefix in bkpt-dbg-file-prefixes" (let ((flen (length fname)) (count 0)) (labels ((rec (prefixes) (incf count) (dbgprt (format "rec %4d: %d prefixes\n" count (length prefixes))) (if prefixes (let* ((p (car prefixes)) (plen (length p))) (or (and (>= flen plen) (equal (substring fname 0 plen) p)) (rec (cdr prefixes))))))) (rec bkpt-dbg-file-prefixes)))) (defun bkpt-bkp-name (base) "string from base-revt-date" (let ((date-time (format-time-string "%Y%m%d-%H%M%S"))) (format "%s-bkpt-%s" base date-time))) (defun get-breakpoints-buf (buf auto-revt) "return list of all breakpoints in BUF as \"filename:lineno\" strings" (with-current-buffer buf (save-excursion (let ((pos) (fname (car (last (split-string buffer-file-name "/+")))) (bpts nil)) (if (not (verify-visited-file-modtime buf)) (if auto-revt (let ((bkp-fname (bkpt-bkp-name fname))) (message (format "backing up obsolete buffer %s to %s before revert" fname bkp-fname)) (write-file bkp-fname) (set-visited-file-name fname t) ; write-file changed it. (revert-buffer nil t)) (error "buffer for %s is obsolete" fname))) (goto-char (point-min)) (while (setq pos (search-forward bkpt-marker-string nil t)) (dbgprt (format "get-breakpoints-buf: in %s found %d" fname pos)) (forward-line 3) (let ((entry (format "break %s:%d" fname (count-lines (point-min) (point))))) (setq bpts (cons entry bpts)))) bpts)))) (defun get-breakpoints (auto-revt) "find all breakpoints in the bkpt-dbg-files" (let ((acc) (count 0)) (mapc (lambda (buf) (let ((fname (with-current-buffer buf buffer-file-name))) (setq count (1+ count)) (if (and fname bkpt-dbg-buffer) (dbgprt (format "%3d: %s\n" count fname))) (if (and (not (member fname bkpt-dbg-excluded-files)) (or (bkpt-prefix-match fname) (member fname bkpt-dbg-files))) (progn (dbgprt (format "%3d: %s MEMBER\n" count fname)) (setq acc (append (get-breakpoints-buf buf auto-revt) acc)))))) (buffer-list)) acc)) (defun cmds-breakpoints (user-prefix) "list gdb commands for breakpoints found in open files from bkpt-dbg-files" (interactive "p") (insert (let* ((auto-revt (> user-prefix 1)) (bpts (get-breakpoints auto-revt))) (with-temp-buffer (mapc (lambda (s) (insert (concat s "\n"))) bpts) (let ((s (buffer-string))) (if (> (length s) 0) (substring s 0 -1) ""))))))