From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Phil Sainty Newsgroups: gmane.emacs.bugs Subject: bug#27397: [PATCH] New commands for bulk tracing of elisp functions Date: Sun, 18 Jun 2017 23:22:31 +1200 Message-ID: References: <1348823a-7623-8146-8cc0-8c0eff13e458@orcon.net.nz> <94d27dbb-46d3-1d6f-4849-251a0929d413@orcon.net.nz> <70000e90-328c-c084-3e3c-bbde96b16110@orcon.net.nz> <6b195c26-066c-870f-3432-0b24c6f619ec@orcon.net.nz> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------5BDDD4D8641D5478F16D92E0" X-Trace: blaine.gmane.org 1497785062 27016 195.159.176.226 (18 Jun 2017 11:24:22 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Sun, 18 Jun 2017 11:24:22 +0000 (UTC) User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.1.1 To: 27397@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Sun Jun 18 13:24:13 2017 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dMYJR-0006WE-HG for geb-bug-gnu-emacs@m.gmane.org; Sun, 18 Jun 2017 13:24:13 +0200 Original-Received: from localhost ([::1]:37926 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dMYJW-0005yZ-FV for geb-bug-gnu-emacs@m.gmane.org; Sun, 18 Jun 2017 07:24:18 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:36540) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dMYJL-0005yU-KY for bug-gnu-emacs@gnu.org; Sun, 18 Jun 2017 07:24:09 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dMYJG-0006Qu-L6 for bug-gnu-emacs@gnu.org; Sun, 18 Jun 2017 07:24:07 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:51354) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dMYJG-0006Qo-FI for bug-gnu-emacs@gnu.org; Sun, 18 Jun 2017 07:24:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1dMYJG-0005bu-5m for bug-gnu-emacs@gnu.org; Sun, 18 Jun 2017 07:24:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Phil Sainty Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 18 Jun 2017 11:24:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 27397 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch X-Debbugs-Original-To: bug-gnu-emacs@gnu.org Original-Received: via spool by submit@debbugs.gnu.org id=B.149778499021496 (code B ref -1); Sun, 18 Jun 2017 11:24:02 +0000 Original-Received: (at submit) by debbugs.gnu.org; 18 Jun 2017 11:23:10 +0000 Original-Received: from localhost ([127.0.0.1]:54031 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dMYIQ-0005ad-4N for submit@debbugs.gnu.org; Sun, 18 Jun 2017 07:23:10 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:45453) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dMYIO-0005aN-8L for submit@debbugs.gnu.org; Sun, 18 Jun 2017 07:23:09 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dMYIG-0005ka-S0 for submit@debbugs.gnu.org; Sun, 18 Jun 2017 07:23:03 -0400 Original-Received: from lists.gnu.org ([2001:4830:134:3::11]:38817) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dMYIG-0005k5-NP for submit@debbugs.gnu.org; Sun, 18 Jun 2017 07:23:00 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:36410) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dMYIE-0005qW-5h for bug-gnu-emacs@gnu.org; Sun, 18 Jun 2017 07:23:00 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dMYI9-0005cp-6t for bug-gnu-emacs@gnu.org; Sun, 18 Jun 2017 07:22:58 -0400 Original-Received: from smtp-3.orcon.net.nz ([60.234.4.44]:46220) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dMYI8-0005a2-K1 for bug-gnu-emacs@gnu.org; Sun, 18 Jun 2017 07:22:53 -0400 Original-Received: from [150.107.172.87] (port=24191 helo=[192.168.20.102]) by smtp-3.orcon.net.nz with esmtpa (Exim 4.86_2) (envelope-from ) id 1dMYHo-0002fl-Br for bug-gnu-emacs@gnu.org; Sun, 18 Jun 2017 23:22:42 +1200 In-Reply-To: <6b195c26-066c-870f-3432-0b24c6f619ec@orcon.net.nz> Content-Language: en-US X-GeoIP: NZ X-Spam_score: -1.0 X-Spam_score_int: -9 X-Spam_bar: - X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:133724 Archived-At: This is a multi-part message in MIME format. --------------5BDDD4D8641D5478F16D92E0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit Just attaching the current patch. Thanks for the input Dmitry and Kaushal. I'll leave it a while to see whether anyone else wishes to weigh in on the outstanding items: * The inconsistent predicate naming of `trace-is-traced' vs `trace-is-traceable-p'. https://debbugs.gnu.org/cgi/bugreport.cgi?bug=27397#19 * Whether foreground-tracing variants of the new commands are wanted. https://debbugs.gnu.org/cgi/bugreport.cgi?bug=27397#25 https://debbugs.gnu.org/cgi/bugreport.cgi?bug=27397#34 * Whether it's a good idea to display the trace buffer initially when one of the background tracing commands is invoked. (I guess I'll follow up next weekend if no one has anything to add in the interim.) -Phil --------------5BDDD4D8641D5478F16D92E0 Content-Type: text/x-patch; name="0001-New-commands-for-bulk-tracing-of-elisp-functions.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename*0="0001-New-commands-for-bulk-tracing-of-elisp-functions.patch" >From 5ca9108f585a06c2085ab180c390bf85d3657230 Mon Sep 17 00:00:00 2001 From: Phil Sainty Date: Sun, 11 Jun 2017 17:29:53 +1200 Subject: [PATCH] New commands for bulk tracing of elisp functions * lisp/emacs-lisp/trace.el (trace-package, untrace-package) (trace-regexp, untrace-regexp, trace-is-traceable-p): New functions. (trace--read-function): New function, split from `trace--read-args'. Changed to use the new `trace-is-traceable-p' predicate. (trace--read-extra-args): New function, split from `trace--read-args'. Changed to allow the user to enter an empty string at the context expression prompt (previously an error; now treated as "nil"), and to cause a "nil" context expression to produce no context output in the trace buffer. (trace--read-args): Removed function. Replaced by the combination of `trace--read-function' and `trace--read-extra-args'. (trace-function-foreground, trace-function-background): Updated interactive specs to use the new functions. (trace-is-traced, untrace-function, untrace-all): Doc updates/fixes. Commentary updated to cover the new commands. Change log updated to cover the main changes since 1993. * etc/NEWS: Mention the new trace commands. * doc/misc/tramp.texi: Update "(tramp) Traces and Profiles" to use `trace-package'. --- doc/misc/tramp.texi | 4 +- etc/NEWS | 8 ++ lisp/emacs-lisp/trace.el | 206 ++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 176 insertions(+), 42 deletions(-) diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 4ca3932..54d5d00 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -3672,9 +3672,7 @@ Traces and Profiles @lisp @group -(require 'trace) -(dolist (elt (all-completions "tramp-" obarray 'functionp)) - (trace-function-background (intern elt))) +(trace-package "tramp-") (untrace-function 'tramp-read-passwd) @end group @end lisp diff --git a/etc/NEWS b/etc/NEWS index 7972511..d3d73cc 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -743,6 +743,14 @@ header's value. where the GnuPG home directory (used for signature verification) is located and whether GnuPG's option "--homedir" is used or not. +** Trace + ++++ +*** New commands 'trace-package' and 'trace-regexp' (and their +counterparts 'untrace-package' and 'untrace-regexp') allow for the +bulk tracing of calls to functions with names matching a specified +prefix or regexp. + ** Tramp +++ diff --git a/lisp/emacs-lisp/trace.el b/lisp/emacs-lisp/trace.el index 1c57d73..05ee780 100644 --- a/lisp/emacs-lisp/trace.el +++ b/lisp/emacs-lisp/trace.el @@ -52,14 +52,20 @@ ;; Usage: ;; ====== -;; - To trace a function say `M-x trace-function', which will ask you for the +;; - To trace a function use `M-x trace-function', which will ask you for the ;; name of the function/subr/macro to trace. ;; - If you want to trace a function that switches buffers or does other ;; display oriented stuff use `M-x trace-function-background', which will ;; generate the trace output silently in the background without popping ;; up windows and doing other irritating stuff. -;; - To untrace a function say `M-x untrace-function'. -;; - To untrace all currently traced functions say `M-x untrace-all'. +;; - `M-x trace-package' will ask you for a function name prefix, and trace +;; (in the background) all matching functions. +;; - `M-x trace-regexp' will ask you for a function name pattern (regexp), +;; and trace (in the background) all matching functions. +;; - To untrace a function use `M-x untrace-function'. +;; - To untrace multiple functions by prefix use `M-x untrace-package'. +;; - To untrace multiple functions by regexp use `M-x untrace-regexp'. +;; - To untrace all currently traced functions use `M-x untrace-all'. ;; Examples: ;; ========= @@ -120,6 +126,22 @@ ;;; Change Log: +;; 2017-06-17 Phil Sainty +;; * New commands `trace-package', `untrace-package', `trace-regexp', +;; `untrace-regexp' +;; +;; 2012-2014 Stefan Monnier, Glenn Morris +;; * Adapted for nadvice.el +;; * New `context' argument and display in trace buffer +;; * `trace-function' renamed to (and now an alias of) +;; `trace-function-foreground' +;; +;; 2005-02-27 Stefan Monnier +;; * New `inhibit-trace' variable +;; +;; 1998-04-05 Stephen Eglen +;; * New customize group `trace' +;; ;; Revision 2.0 1993/05/18 00:41:16 hans ;; * Adapted for advice.el 2.0; it now also works ;; for GNU Emacs-19 and Lemacs @@ -257,42 +279,48 @@ trace-function-internal (or context (lambda () ""))) `((name . ,trace-advice-name) (depth . -100)))) +(defun trace-is-traceable-p (sym) + "Whether the given symbol is a traceable function." + (or (functionp sym) (macrop sym))) + (defun trace-is-traced (function) + "Whether FUNCTION is currently traced." (advice-member-p trace-advice-name function)) -(defun trace--read-args (prompt) - "Read a function name, prompting with string PROMPT. -If `current-prefix-arg' is non-nil, also read a buffer and a \"context\" -\(Lisp expression). Return (FUNCTION BUFFER FUNCTION-CONTEXT)." - (cons - (let ((default (function-called-at-point)) - (beg (string-match ":[ \t]*\\'" prompt))) - (intern (completing-read (if default - (format - "%s (default %s)%s" - (substring prompt 0 beg) - default - (if beg (substring prompt beg) ": ")) - prompt) - obarray 'fboundp t nil nil - (if default (symbol-name default))))) - (when current-prefix-arg - (list - (read-buffer "Output to buffer: " trace-buffer) - (let ((exp - (let ((minibuffer-completing-symbol t)) - (read-from-minibuffer "Context expression: " - nil read-expression-map t - 'read-expression-history)))) - (lambda () - (let ((print-circle t)) - (concat " [" (prin1-to-string (eval exp t)) "]")))))))) +(defun trace--read-function (prompt) + "Read a function name, prompting with string PROMPT." + (let ((default (function-called-at-point)) + (beg (string-match ":[ \t]*\\'" prompt))) + (intern (completing-read (if default + (format + "%s (default %s)%s" + (substring prompt 0 beg) + default + (if beg (substring prompt beg) ": ")) + prompt) + obarray 'trace-is-traceable-p t nil nil + (if default (symbol-name default)))))) + +(defun trace--read-extra-args () + "Read a buffer and a \"context\" (Lisp expression). +Return (BUFFER CONTEXT)." + (list + (read-buffer "Output to buffer: " trace-buffer) + (let ((exp + (let ((minibuffer-completing-symbol t)) + (read-from-minibuffer "Context expression: " + nil read-expression-map t + 'read-expression-history "nil")))) + (and exp + (lambda () + (let ((print-circle t)) + (concat " [" (prin1-to-string (eval exp t)) "]"))))))) ;;;###autoload (defun trace-function-foreground (function &optional buffer context) "Trace calls to function FUNCTION. -With a prefix argument, also prompt for the trace buffer (default -`trace-buffer'), and a Lisp expression CONTEXT. +With a prefix argument, also prompt for the trace output BUFFER +\(default `trace-buffer'), and a Lisp expression CONTEXT. Tracing a function causes every call to that function to insert into BUFFER Lisp-style trace messages that display the function's @@ -306,7 +334,9 @@ trace-function-foreground stuff - use `trace-function-background' instead. To stop tracing a function, use `untrace-function' or `untrace-all'." - (interactive (trace--read-args "Trace function: ")) + (interactive + (cons (trace--read-function "Trace function: ") + (and current-prefix-arg (trace--read-extra-args)))) (trace-function-internal function buffer nil context)) ;;;###autoload @@ -314,24 +344,122 @@ trace-function-background "Trace calls to function FUNCTION, quietly. This is like `trace-function-foreground', but without popping up the output buffer or changing the window configuration." - (interactive (trace--read-args "Trace function in background: ")) + (interactive + (cons (trace--read-function "Trace function in background: ") + (and current-prefix-arg (trace--read-extra-args)))) (trace-function-internal function buffer t context)) ;;;###autoload (defalias 'trace-function 'trace-function-foreground) (defun untrace-function (function) - "Untraces FUNCTION and possibly activates all remaining advice. -Activation is performed with `ad-update', hence remaining advice will get -activated only if the advice of FUNCTION is currently active. If FUNCTION -was not traced this is a noop." + "Remove trace from FUNCTION. If FUNCTION was not traced this is a noop." (interactive (list (intern (completing-read "Untrace function: " obarray #'trace-is-traced t)))) (advice-remove function trace-advice-name)) +;;;###autoload +(defun trace-package (prefix &optional buffer context) + "Trace all functions with names starting with PREFIX. +For example, to trace all diff functions, do the following: + +\\[trace-package] RET diff- RET + +With a prefix argument, also prompt for the trace output BUFFER +\(default `trace-buffer'), and a Lisp expression CONTEXT. + +Background tracing is used. Switch to the trace output buffer to view +the results. + +See `trace-function-foreground' for details on the optional arguments +and foreground vs background tracing. + +See also `untrace-package'." + ;; Derived in part from `elp-instrument-package'. + (interactive + (cons (completing-read "Prefix of package to trace: " + obarray #'trace-is-traceable-p) + (and current-prefix-arg (trace--read-extra-args)))) + (when (zerop (length prefix)) + (error "Tracing all Emacs functions would render Emacs unusable")) + (mapc (lambda (name) + (trace-function-background (intern name) buffer context)) + (all-completions prefix obarray #'trace-is-traceable-p)) + (message + "Tracing to %s. Use %s to untrace a package, or %s to remove all traces." + (or buffer trace-buffer) + (substitute-command-keys "\\[untrace-package]") + (substitute-command-keys "\\[untrace-all]"))) + +(defun untrace-package (prefix) + "Remove all traces from functions with names starting with PREFIX. + +See also `trace-package'." + (interactive + (list (completing-read "Prefix of package to untrace: " + obarray #'trace-is-traced))) + (if (and (zerop (length prefix)) + (y-or-n-p "Remove all function traces?")) + (untrace-all) + (mapc (lambda (name) + (untrace-function (intern name))) + (all-completions prefix obarray #'trace-is-traceable-p)))) + +;;;###autoload +(defun trace-regexp (regexp &optional buffer context) + "Trace all functions with names matching REGEXP. +For example, to trace indentation-related functions, you could try: + +\\[trace-regexp] RET indent\\|offset RET + +Warning: Do not attempt to trace all functions. Tracing too many +functions at one time will render Emacs unusable. + +With a prefix argument, also prompt for the trace output BUFFER +\(default `trace-buffer'), and a Lisp expression CONTEXT. + +Background tracing is used. Switch to the trace output buffer to view +the results. + +See `trace-function-foreground' for details on the optional arguments +and foreground vs background tracing. + +See also `untrace-regexp'." + (interactive + (cons (read-regexp "Regexp matching functions to trace: ") + (and current-prefix-arg (trace--read-extra-args)))) + (when (member regexp '("" "." ".+" ".*")) + ;; Not comprehensive, but it catches the most likely attempts. + (error "Tracing all Emacs functions would render Emacs unusable")) + (mapatoms + (lambda (sym) + (and (trace-is-traceable-p sym) + (string-match-p regexp (symbol-name sym)) + (trace-function-background sym buffer context)))) + (message + "Tracing to %s. Use %s to untrace by regexp, or %s to remove all traces." + (or buffer trace-buffer) + (substitute-command-keys "\\[untrace-regexp]") + (substitute-command-keys "\\[untrace-all]"))) + +(defun untrace-regexp (regexp) + "Remove all traces from functions with names matching REGEXP. + +See also `trace-regexp'." + (interactive + (list (read-regexp "Regexp matching functions to untrace: "))) + (if (and (zerop (length regexp)) + (y-or-n-p "Remove all function traces?")) + (untrace-all) + (mapatoms + (lambda (sym) + (and (trace-is-traceable-p sym) + (string-match-p regexp (symbol-name sym)) + (untrace-function sym)))))) + (defun untrace-all () - "Untraces all currently traced functions." + "Remove traces from all currently traced functions." (interactive) (mapatoms #'untrace-function)) -- 2.8.3 --------------5BDDD4D8641D5478F16D92E0--