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 00:31:10 +1200 Message-ID: <70000e90-328c-c084-3e3c-bbde96b16110@orcon.net.nz> References: <1348823a-7623-8146-8cc0-8c0eff13e458@orcon.net.nz> <94d27dbb-46d3-1d6f-4849-251a0929d413@orcon.net.nz> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------E1EE229F6C2D01E03D4D939F" X-Trace: blaine.gmane.org 1497702742 12507 195.159.176.226 (17 Jun 2017 12:32:22 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Sat, 17 Jun 2017 12:32: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 Sat Jun 17 14:32:17 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 1dMCtj-0002lw-HN for geb-bug-gnu-emacs@m.gmane.org; Sat, 17 Jun 2017 14:32:15 +0200 Original-Received: from localhost ([::1]:34580 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dMCtn-00044J-2O for geb-bug-gnu-emacs@m.gmane.org; Sat, 17 Jun 2017 08:32:19 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:39630) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dMCtZ-00044A-T4 for bug-gnu-emacs@gnu.org; Sat, 17 Jun 2017 08:32:09 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dMCtW-0007yS-Os for bug-gnu-emacs@gnu.org; Sat, 17 Jun 2017 08:32:05 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:49525) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dMCtW-0007yO-Kk for bug-gnu-emacs@gnu.org; Sat, 17 Jun 2017 08:32:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1dMCtW-0001Hl-Es for bug-gnu-emacs@gnu.org; Sat, 17 Jun 2017 08:32: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: Sat, 17 Jun 2017 12:32: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.14977026934900 (code B ref -1); Sat, 17 Jun 2017 12:32:02 +0000 Original-Received: (at submit) by debbugs.gnu.org; 17 Jun 2017 12:31:33 +0000 Original-Received: from localhost ([127.0.0.1]:52202 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dMCt3-0001Gx-94 for submit@debbugs.gnu.org; Sat, 17 Jun 2017 08:31:33 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:48591) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dMCt1-0001Gi-Cj for submit@debbugs.gnu.org; Sat, 17 Jun 2017 08:31:31 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dMCsu-0007km-Ig for submit@debbugs.gnu.org; Sat, 17 Jun 2017 08:31:26 -0400 Original-Received: from lists.gnu.org ([2001:4830:134:3::11]:51882) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dMCsu-0007kg-E6 for submit@debbugs.gnu.org; Sat, 17 Jun 2017 08:31:24 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:39560) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dMCss-00042T-Dj for bug-gnu-emacs@gnu.org; Sat, 17 Jun 2017 08:31:24 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dMCsp-0007kP-A0 for bug-gnu-emacs@gnu.org; Sat, 17 Jun 2017 08:31:22 -0400 Original-Received: from smtp-1.orcon.net.nz ([60.234.4.34]:47346) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dMCso-0007kG-NS for bug-gnu-emacs@gnu.org; Sat, 17 Jun 2017 08:31:19 -0400 Original-Received: from [150.107.172.84] (port=6352 helo=[192.168.20.102]) by smtp-1.orcon.net.nz with esmtpa (Exim 4.86_2) (envelope-from ) id 1dMCsh-0003YN-IG for bug-gnu-emacs@gnu.org; Sun, 18 Jun 2017 00:31:15 +1200 In-Reply-To: <94d27dbb-46d3-1d6f-4849-251a0929d413@orcon.net.nz> Content-Language: en-GB 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:133695 Archived-At: This is a multi-part message in MIME format. --------------E1EE229F6C2D01E03D4D939F Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit On 17/06/17 21:20, Phil Sainty wrote: > inconsistent with `trace--read-args' which uses a prefix arg to prompt > the user for the trace buffer and a context expression -- which I now > realise is behaviour that my commands should incorporate as well. I've implemented this change, and attached the current WIP patch. In the process I noticed that the existing behaviour of trace--read-args was quite unfriendly if you wanted to set a trace buffer but had no need of a context expression -- typing RET at the context expression prompt triggered an "End of file during parsing" error, as that input string is processed by `read-from-string'. I've changed that code to treat an empty input as "nil" (which is read to `nil'), and to ignore `nil' context expressions entirely (as opposed to printing their evaluated value as "[nil]" in the trace buffer). -Phil --------------E1EE229F6C2D01E03D4D939F 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 4d9ea7ac95b070d55b8e1502c3091168891f433e 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-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-function-args): New name for `trace--read-args'. Changed to use the new `trace-is-traceable-p' predicate. (trace--read-args): Renamed to `trace--read-function-args' (trace-function-foreground, trace-function-background): Call the renamed `trace--read-function-args'. (trace-is-traced, untrace-function, untrace-all): Doc updates/fixes. * 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 | 133 ++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 123 insertions(+), 22 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..949bb54 100644 --- a/lisp/emacs-lisp/trace.el +++ b/lisp/emacs-lisp/trace.el @@ -257,10 +257,15 @@ 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) +(defun trace--read-function-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)." @@ -274,19 +279,25 @@ trace--read-args default (if beg (substring prompt beg) ": ")) prompt) - obarray 'fboundp t nil nil + obarray 'trace-is-traceable-p 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)) "]")))))))) + (trace--read-extra-args)))) + +(defun trace--read-extra-args () + "Read a buffer and a \"context\" (Lisp expression). +Return (BUFFER FUNCTION-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) @@ -306,7 +317,7 @@ 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 (trace--read-function-args "Trace function: ")) (trace-function-internal function buffer nil context)) ;;;###autoload @@ -314,24 +325,108 @@ 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 (trace--read-function-args "Trace function in background: ")) (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 + +Background tracing is used. Switch to the trace output buffer to +view the results. + +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 traces from all 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. + +Background tracing is used. Switch to the trace output buffer to +view the results. + +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 traces from all 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 --------------E1EE229F6C2D01E03D4D939F--