From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: =?UTF-8?Q?Cl=c3=a9ment_Pit--Claudel?= Newsgroups: gmane.emacs.devel Subject: Re: Lisp-friendly backtraces [was: Lispy backtraces] Date: Mon, 5 Dec 2016 09:14:38 -0500 Message-ID: <81066f70-ceed-af88-43ce-c8baefde189a@gmail.com> References: <20160922231447.GA3833@odonien.localdomain> <98fbb582-3da4-bd83-a2e9-e341dd7f6140@gmail.com> <20160923075116.GA612@odonien.localdomain> <82e39377-f31b-698c-5a9a-343868686799@gmail.com> <20161202005226.GA4215@odonien.localdomain> <0a69afa7-e9e6-e75f-8e90-6438683db98d@gmail.com> <53ba4534-1ec3-4e4f-d929-1a72f79c1abe@gmail.com> <83mvgblniy.fsf@gnu.org> <143c480c-a9db-7053-4b70-175633197981@gmail.com> <83a8cbl94w.fsf@gnu.org> <233f14a0-7542-5d0c-d8da-209e7e5e54f7@gmail.com> <838trvkq72.fsf@gnu.org> <27574c57-658c-c87b-4ddc-b24f83e2867c@gmail.com> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="PLPLgr2edde1kjUgAQiBPLvb0GOgUPBBB" X-Trace: blaine.gmane.org 1480947347 4696 195.159.176.226 (5 Dec 2016 14:15:47 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Mon, 5 Dec 2016 14:15:47 +0000 (UTC) User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.5.1 To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon Dec 05 15:15:43 2016 Return-path: Envelope-to: ged-emacs-devel@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 1cDu3S-0000tw-Hc for ged-emacs-devel@m.gmane.org; Mon, 05 Dec 2016 15:15:42 +0100 Original-Received: from localhost ([::1]:40710 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cDu3W-0004jc-Fr for ged-emacs-devel@m.gmane.org; Mon, 05 Dec 2016 09:15:46 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:42371) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cDu2i-0004jW-Rz for emacs-devel@gnu.org; Mon, 05 Dec 2016 09:14:58 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cDu2f-0003bA-Fu for emacs-devel@gnu.org; Mon, 05 Dec 2016 09:14:56 -0500 Original-Received: from mout.kundenserver.de ([212.227.126.131]:62806) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cDu2f-0003Zm-4V for emacs-devel@gnu.org; Mon, 05 Dec 2016 09:14:53 -0500 Original-Received: from [18.189.106.208] ([18.189.106.208]) by mrelayeu.kundenserver.de (mreue003 [212.227.15.168]) with ESMTPSA (Nemesis) id 0MIj6a-1cG6xm45fc-002ETK for ; Mon, 05 Dec 2016 15:14:51 +0100 In-Reply-To: X-Provags-ID: V03:K0:orZIKSkVEhBFSxT1yzds9W7WaTFytam/YehoACk0tjmftPE1+l+ GxpZh1xEMd1ngwml1HzVTarbangwnyOiQMDMExFEy3I/wSwi9OojNQsx9crON/nrioSJKin 0k4CirCfeGTKDRjroO028Of/+OgK9S24xpe0prCLFK18EGOELzpMJvxpAe2YEnzOXi4yxaG NS1AJLw3LPub3oHnQeVmw== X-UI-Out-Filterresults: notjunk:1;V01:K0:5Xl+T1NYQ0Q=:w/VOsix7WiidQWJz8zC9nA 5wzv6X/M1OOAzXuIqH4eLAbyKWoYnMnyTWm06XM2wySjRH46juLy1K1CWhhCZcxp34DXi9+Bn VX6JmOuuZjcZWwq9Fc/AGj251iy1STr2lZwzktY78lhNfVmzb05M3NlvcasWFbIwqtW/XYbBO 1UFrO7OiHP+NFueMtGd4XTA4APnzMbKRJuNU64J4AbBlyzTvlK3Iggb+IUskzDbSlDiVoClCL JvzMKklSteGJnrCVA1D3C4eXBI+cwdt7J3Z4SbYOAmE9WvcdZiLEEVdcgEI+aLji9qTrUfFeG phjNtY/yCyTu3pz+5HOH23jwjVYedBAew1Hnyq2rk0zSlPHiDqI/zNoEs7PxubgFWhzCnHcjT J01hKwseRzz7ccNnmWs8pEnjWA6fnttEa6PlE6UpnuExrXx53iwrUAy5M2Z45yWYHceW26DB6 ke1GTW13Whm9lhKFfLwLaxC5NYnJUl/s2NavHEtzIIfg1JdBKC5ZgPmR8ucoLqfilDvfk72HP rA1xaL33gxnOd6h9RNhCwySCEgwF4dKJ3oRcOaLU6/QCA61m52eVe0/JkMKVjxWcKJg3mpx3I sCRTx8GrXx9QJ0UU5mUx3w+LFtytqh+2HVno8P2Wd7eP4VMfOaVt+Q8OslOh09A85q1qtIz0G gdO2J/YknkwnfIr+IijpvJIBVT1jGB2Ow+pxKv268xD2urMWnm9MCnDadWT31n/c0EwE= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.126.131 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:210059 Archived-At: This is an OpenPGP/MIME signed message (RFC 4880 and 3156) --PLPLgr2edde1kjUgAQiBPLvb0GOgUPBBB Content-Type: multipart/mixed; boundary="Ofp27a880MeGp9BJMRO3P4ms74lcvj8fd"; protected-headers="v1" From: =?UTF-8?Q?Cl=c3=a9ment_Pit--Claudel?= To: emacs-devel@gnu.org Message-ID: <81066f70-ceed-af88-43ce-c8baefde189a@gmail.com> Subject: Re: Lisp-friendly backtraces [was: Lispy backtraces] References: <20160922231447.GA3833@odonien.localdomain> <98fbb582-3da4-bd83-a2e9-e341dd7f6140@gmail.com> <20160923075116.GA612@odonien.localdomain> <82e39377-f31b-698c-5a9a-343868686799@gmail.com> <20161202005226.GA4215@odonien.localdomain> <0a69afa7-e9e6-e75f-8e90-6438683db98d@gmail.com> <53ba4534-1ec3-4e4f-d929-1a72f79c1abe@gmail.com> <83mvgblniy.fsf@gnu.org> <143c480c-a9db-7053-4b70-175633197981@gmail.com> <83a8cbl94w.fsf@gnu.org> <233f14a0-7542-5d0c-d8da-209e7e5e54f7@gmail.com> <838trvkq72.fsf@gnu.org> <27574c57-658c-c87b-4ddc-b24f83e2867c@gmail.com> In-Reply-To: --Ofp27a880MeGp9BJMRO3P4ms74lcvj8fd Content-Type: multipart/mixed; boundary="------------25C5F50D74935EBAC1C8BEFF" This is a multi-part message in MIME format. --------------25C5F50D74935EBAC1C8BEFF Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: quoted-printable On 2016-12-05 08:20, Stefan Monnier wrote: >> (defun backtrace () >> "Print a trace of Lisp function calls currently active. >> Output stream used is value of `standard-output'." >> (mapbacktrace #'~/backtrace-1 1)) >=20 > Have you tried it both byte-compiled and interpreted? Maybe this > function is just simple enough that the result is the same in both > cases, but in my experience, the stack is sufficiently different in the= > two cases that a constant nskip doesn't cut it (hence the use of `base`= > in backtrace-frame). Thanks; I attached an updated patch. Removing `backtrace' from eval.c ma= kes the patch much harder to read, so I'll do that later. Cl=E9ment. --------------25C5F50D74935EBAC1C8BEFF Content-Type: text/x-emacs-lisp; name="bt.el" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="bt.el" ;; -*- lexical-binding: t -*- (defun backtrace-1 (evald func args flags) "Print a trace of a single stack frame to `standard-output'. EVALD, FUNC, ARGS, FLAGS are as in `mapbacktrace'." (let ((print-level (or print-level 8))) (princ (if (plist-get flags :debug-on-exit) "* " " ")) (cond ((and evald (not debugger-stack-frame-as-list)) (prin1 func) (if args (prin1 args) (princ "()"))) (t (prin1 (cons func args)))) (princ "\n"))) (defun backtrace () "Print a trace of Lisp function calls currently active. Output stream used is value of `standard-output'." (mapbacktrace #'backtrace-1 'backtrace)) (backtrace) (defun backtrace-frames () "Collect all frames of current backtrace into a list." (let ((frames nil)) (mapbacktrace (lambda (&rest frame) (push frame frames)) 'backtrace-f= rames) (nreverse frames))) (backtrace-frames) (defun ~/backtrace-frame (nframes &optional base) "Return the function and arguments NFRAMES up from current execution po= int. If that frame has not evaluated the arguments yet (or is a special form),= the value is (nil FUNCTION ARG-FORMS...). If that frame has evaluated its arguments and called its function already= , the value is (t FUNCTION ARG-VALUES...). A &rest arg is represented as the tail of the list ARG-VALUES. FUNCTION is whatever was supplied as car of evaluated list, or a lambda expression for macro calls. If NFRAMES is more than the number of frames, the value is nil. If BASE is non-nil, it should be a function and NFRAMES counts from its nearest activation frame." (let ((frame nil)) (mapbacktrace (lambda (evald func args _) (when (and base (eq func base)) (setq base nil)) (unless base (when (eq nframes 0) (setq frame `(,evald ,func ,@args))) (setq nframes (1- nframes)))) '~/backtrace-frame) frame)) --------------25C5F50D74935EBAC1C8BEFF Content-Type: text/x-diff; name="0001-New-function-mapbacktrace.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="0001-New-function-mapbacktrace.patch" =46rom 6302757b6fc664a8ef56ff8742aaf1987e58107d Mon Sep 17 00:00:00 2001 From: =3D?UTF-8?q?Cl=3DC3=3DA9ment=3D20Pit--Claudel?=3D Date: Mon, 5 Dec 2016 00:52:14 -0500 Subject: [PATCH] New function mapbacktrace --- src/eval.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++---= ------ 1 file changed, 57 insertions(+), 9 deletions(-) diff --git a/src/eval.c b/src/eval.c index 724f001..66b665e 100644 --- a/src/eval.c +++ b/src/eval.c @@ -3420,6 +3420,60 @@ The debugger is entered when that frame exits, if = the flag is non-nil. */) return flag; } =20 +static union specbinding * +get_backtrace_starting_at (Lisp_Object base) +{ + union specbinding *pdl =3D backtrace_top (); + + if (!NILP (base)) + { /* Skip up to `base'. */ + base =3D Findirect_function (base, Qt); + while (backtrace_p (pdl) + && !EQ (base, Findirect_function (backtrace_function (pdl),= Qt))) + pdl =3D backtrace_next (pdl); + } + + return pdl; +} + +DEFUN ("mapbacktrace", Fmapbacktrace, Smapbacktrace, 1, 2, 0, + doc: /* Call FUNCTION for each frame in backtrace. +FUNCTION is called with 4 arguments EVALD FUNC ARGS FLAGS. If a frame +has not evaluated its arguments yet or is a special form, EVALD is nil +and ARGS is a list of forms. If a frame has evaluated its arguments +and called its function already, EVALD is t and ARGS is a list of +values. FLAGS is a plist of properties of the current frame: +currently, the only supported property is :debug-on-exit. +If BASE is non-nil, it should be a function and iteration will start +from its nearest activation frame. +`mapbacktrace' always returns nil. */) + (Lisp_Object function, Lisp_Object base) +{ + union specbinding *pdl =3D get_backtrace_starting_at (base); + + while (backtrace_p (pdl)) + { + Lisp_Object flags =3D Qnil; + if (backtrace_debug_on_exit (pdl)) + { + flags =3D Fcons (QCdebug_on_exit, Fcons (Qt, Qnil)); + } + + if (backtrace_nargs (pdl) =3D=3D UNEVALLED) + { + call4 (function, Qnil, backtrace_function (pdl), *backtrace_ar= gs (pdl), flags); + } + else + { + Lisp_Object tem =3D Flist (backtrace_nargs (pdl), backtrace_ar= gs (pdl)); + call4 (function, Qt, backtrace_function (pdl), tem, flags); + } + pdl =3D backtrace_next (pdl); + } + + return Qnil; +} + DEFUN ("backtrace", Fbacktrace, Sbacktrace, 0, 0, "", doc: /* Print a trace of Lisp function calls currently active. Output stream used is value of `standard-output'. */) @@ -3470,18 +3524,10 @@ Output stream used is value of `standard-output'.= */) static union specbinding * get_backtrace_frame (Lisp_Object nframes, Lisp_Object base) { - union specbinding *pdl =3D backtrace_top (); register EMACS_INT i; =20 CHECK_NATNUM (nframes); - - if (!NILP (base)) - { /* Skip up to `base'. */ - base =3D Findirect_function (base, Qt); - while (backtrace_p (pdl) - && !EQ (base, Findirect_function (backtrace_function (pdl), Qt))) - pdl =3D backtrace_next (pdl); - } + union specbinding *pdl =3D get_backtrace_starting_at (base); =20 /* Find the frame requested. */ for (i =3D XFASTINT (nframes); i > 0 && backtrace_p (pdl); i--) @@ -3974,6 +4020,8 @@ alist of active lexical bindings. */); defsubr (&Sfetch_bytecode); defsubr (&Sbacktrace_debug); defsubr (&Sbacktrace); + DEFSYM (QCdebug_on_exit, ":debug-on-exit"); + defsubr (&Smapbacktrace); defsubr (&Sbacktrace_frame); defsubr (&Sbacktrace_eval); defsubr (&Sbacktrace__locals); --=20 2.7.4 --------------25C5F50D74935EBAC1C8BEFF-- --Ofp27a880MeGp9BJMRO3P4ms74lcvj8fd-- --PLPLgr2edde1kjUgAQiBPLvb0GOgUPBBB Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAEBCAAGBQJYRXZOAAoJEPqg+cTm90wjlw4P/AkQhXKrNXHSSzlQJyupmx9u E11QJt2gKX4nZcnGJ7je7N78HBopXd6BIQ/2+U7LxheTla9eBYGtLbnNnx5IHLfV 4t8IjJkYYak97RGFGxwnB/h3EX6GKjMXq8y1cFA9U+yeRAYi2L653+zU5wyg4fPT PMoOrwv1yj1z6EorLnjUpaT7bIJtTkRynSNgUWmsyRC2d1p4hH2nosnDZL+US3wu 7Qc/sZthNrMZLnDAmL8JjREEbxT2unAgbYcxWeE+NeGuQdDh36TtDcrCseCSIlDK daQ5XcV6kQjoZdWTrL/aLI4S4HatxIC88Dcy8H3CJl8XB9ffi1Es97h15zLNcJaz zxhxneRmec1Nic2waQKDgb4SYk1+7JNUoQ1qEh6JLeDqSHbJqJsW1CwGreCCFWEi coyJBsWr5wAOTLhr9pwJ+a1+D9jDEbIxSH/knazd90K/CscR0uxqM8ulh5YQ24Qe /jEm/rF0mhAw+bPtG1/QqKV5m677WVGVxl4nMEHZfo8tRNa6efhYelYeF6ZiwUmC aihj0TAH0LtbH/LbVMoiKF4V+5nIy/ubzOTIqP8Cms6984+AJLysPqwl9Sok6CuG +dzk8lOUGjNG76RWzztus3hwbqv9B/RePqpZGs4UilivqrY+UWLPx//760DRZtkE +hj4fJubO57b+trSEBUr =MlFN -----END PGP SIGNATURE----- --PLPLgr2edde1kjUgAQiBPLvb0GOgUPBBB--