From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Zach Shaftel Newsgroups: gmane.emacs.bugs Subject: bug#42499: [PATCH] Add Bytecode Offset information to Backtrace Date: Thu, 23 Jul 2020 19:29:48 -0400 Message-ID: <87tuxxzucm.fsf@gmail.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="39323"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: mu4e 1.4.10; emacs 28.0.50 To: 42499@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Fri Jul 24 01:31:10 2020 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jykg9-000A7x-Jy for geb-bug-gnu-emacs@m.gmane-mx.org; Fri, 24 Jul 2020 01:31:09 +0200 Original-Received: from localhost ([::1]:53354 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jykg8-0003W5-M4 for geb-bug-gnu-emacs@m.gmane-mx.org; Thu, 23 Jul 2020 19:31:08 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:42558) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jykg2-0003Vx-15 for bug-gnu-emacs@gnu.org; Thu, 23 Jul 2020 19:31:02 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:34763) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jykg1-0000vb-Np for bug-gnu-emacs@gnu.org; Thu, 23 Jul 2020 19:31:01 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1jykg1-0003c2-LD for bug-gnu-emacs@gnu.org; Thu, 23 Jul 2020 19:31:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Zach Shaftel Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 23 Jul 2020 23:31:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 42499 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch X-Debbugs-Original-To: Original-Received: via spool by submit@debbugs.gnu.org id=B.159554701313827 (code B ref -1); Thu, 23 Jul 2020 23:31:01 +0000 Original-Received: (at submit) by debbugs.gnu.org; 23 Jul 2020 23:30:13 +0000 Original-Received: from localhost ([127.0.0.1]:46305 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jykf0-0003YP-3T for submit@debbugs.gnu.org; Thu, 23 Jul 2020 19:30:13 -0400 Original-Received: from lists.gnu.org ([209.51.188.17]:40458) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jykev-0003YE-RG for submit@debbugs.gnu.org; Thu, 23 Jul 2020 19:29:56 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:42212) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jykev-0003ES-KQ for bug-gnu-emacs@gnu.org; Thu, 23 Jul 2020 19:29:53 -0400 Original-Received: from mail-qt1-x82d.google.com ([2607:f8b0:4864:20::82d]:37688) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jyket-0000cT-Kv for bug-gnu-emacs@gnu.org; Thu, 23 Jul 2020 19:29:53 -0400 Original-Received: by mail-qt1-x82d.google.com with SMTP id d27so5728993qtg.4 for ; Thu, 23 Jul 2020 16:29:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=user-agent:from:to:subject:message-id:date:mime-version; bh=K/5X9Y0MkGonFxfpDOYPO+1IjT7XyMuLDmcoX1TjI9A=; b=POKEUg7fXSXvdLv4o8pKnDKHPLAmg8cod2D4iQXxhAo9ShtJS4k8FCBMtXkN6m3iQB UC6+pg4fp6bRXO28Z33oNUA3nOBM68Vi/12OvFeWp8tuU25d480BR2o66voxNg1rD011 wEFUqCDNroo0u5pYEV1lLrxuGr/nYA4/63JU98WjVfOX6GjZKbYLvJ7RbJTecyg5vRb8 O6XVTWpwuDp/1Xih8y8RSlzXxvm5j6SyQZnmVG7Xe0BBjd5+I9vu0SxxU7u02z7B3E5D 0HjNr8lVFDhHj0OQwhNENFzhfpQk3mjrSlrBdzvUfvJj7tIbDGjC8uWzgnVEo+Fz0MaP CRug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:user-agent:from:to:subject:message-id:date :mime-version; bh=K/5X9Y0MkGonFxfpDOYPO+1IjT7XyMuLDmcoX1TjI9A=; b=gllIJ8BDGVxhqpXxqvKcyzRfuxdmI1lbgv3pxMSBgqKfwRhzjOyVa/CIr1DtCFcZvc 5X8APgz4Ve5TXIU4zpZ+XAaldL7cW1qNGxn2RHgqRGiJ+r12jFc4fUOk3waWkB7ffpgQ ZmTFKcY36Oxk10c2pQ1esRoARALOF5Us1VHjGKPWHL8k17Q3YFhKCxKxdZd4SgWn1u1j h8CS48cfD9c0vtzf4+QiQKXTO4El4BEokrMdJIHXAXqXoWUZB97RjI1iKjBfG+pXGPHV lWwHd8h9FaqZxEsQZrkJ6ny5i/mIAUYniel5Y03VMELylJ/3chUsvbovscjg3b6S6nYP B6XQ== X-Gm-Message-State: AOAM530fv0lQSpGMpb8Q0X/gx7tbdH1MOcFSsepAuyM4kM64kPWt7NVI e/+7ur31yxenORoXqxjOMvnEeUiffNc= X-Google-Smtp-Source: ABdhPJy9EjV1PHoQWLVTleyMgbHBqdN1IoBAFL7ZwDhvG22s6ng81exsYv8aoLxJ4t7rxtvpo+7dhA== X-Received: by 2002:ac8:5181:: with SMTP id c1mr6921661qtn.173.1595546989936; Thu, 23 Jul 2020 16:29:49 -0700 (PDT) Original-Received: from arch-thinkpad ([2604:2000:2f41:2d00::1]) by smtp.gmail.com with ESMTPSA id 84sm4513727qkf.136.2020.07.23.16.29.49 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Jul 2020 16:29:49 -0700 (PDT) Received-SPF: pass client-ip=2607:f8b0:4864:20::82d; envelope-from=zshaftel@gmail.com; helo=mail-qt1-x82d.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list 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-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:183467 Archived-At: --=-=-= Content-Type: text/plain This patch adds the offset in a bytecode function's execution where an error occurs to the *Backtrace* buffer, like this: Debugger entered--Lisp error: (wrong-type-argument stringp t) string-match(t t nil) 13 test-condition-case() load("/home/zach/.repos/bench-compare.el/test/test-debug...") 78 byte-recompile-file("/home/zach/.repos/bench-compare.el/test/test-debug..." nil 0 t) 35 emacs-lisp-byte-compile-and-load() funcall-interactively(emacs-lisp-byte-compile-and-load) call-interactively(emacs-lisp-byte-compile-and-load record nil) 101 command-execute(emacs-lisp-byte-compile-and-load record) If you disassemble one of the annotated functions, you can find the instruction where the error occured. A 'bytecode_offset' field is added to the 'specbinding.bt' struct, which holds the offset in the execution of that frame's bytecode function. The offset for the function being executed is stored in a field of the 'thread_state' struct, and updated from within 'exec_byte_code' before a funcall. Then 'record_in_backtrace', called by Ffuncall, finds the last frame and stores the offset there. The frame's offset is added to the FLAGS plist argument passed by 'mapbacktrace'. See further discussion about the limitations of the attached implementation here: https://lists.gnu.org/archive/html/emacs-devel/2020-07/msg00365.html My copyright assignment is still pending so I assume this can't be merged until I hear back from copyright-clerk. The patch attached is a simple diff without commit messages. I can add NEWS and Changelog entries/commit messages if this ends up going through, but I may not be able to get to that until next week. -Zach --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=bytecode-offset-in-backtrace.patch diff --git a/lisp/emacs-lisp/backtrace.el b/lisp/emacs-lisp/backtrace.el index 37dad8db16..f67e1dd72a 100644 --- a/lisp/emacs-lisp/backtrace.el +++ b/lisp/emacs-lisp/backtrace.el @@ -257,7 +257,7 @@ backtrace-mode-map map) "Local keymap for `backtrace-mode' buffers.") -(defconst backtrace--flags-width 2 +(defconst backtrace--flags-width 7 "Width in characters of the flags for a backtrace frame.") ;;; Navigation and Text Properties @@ -746,11 +746,16 @@ backtrace--print-flags "Print the flags of a backtrace FRAME if enabled in VIEW." (let ((beg (point)) (flag (plist-get (backtrace-frame-flags frame) :debug-on-exit)) - (source (plist-get (backtrace-frame-flags frame) :source-available))) + (source (plist-get (backtrace-frame-flags frame) :source-available)) + (offset (plist-get (backtrace-frame-flags frame) :bytecode-offset)) + ;; right justify and pad the offset (or the empty string) + (offset-format (format "%%%ds " (- backtrace--flags-width 3))) + (fun (ignore-errors (indirect-function (backtrace-frame-fun frame))))) (when (plist-get view :show-flags) - (when source (insert ">")) - (when flag (insert "*"))) - (insert (make-string (- backtrace--flags-width (- (point) beg)) ?\s)) + (insert (if source ">" " ")) + (insert (if flag "*" " ")) + (insert (format offset-format + (or (and (byte-code-function-p fun) offset) "")))) (put-text-property beg (point) 'backtrace-section 'func))) (defun backtrace--print-func-and-args (frame _view) diff --git a/src/bytecode.c b/src/bytecode.c index 5ac30aa101..c6766a38cf 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -311,6 +311,10 @@ #define DISCARD(n) (top -= (n)) #define TOP (*top) +/* Update the thread's bytecode offset, just before NEXT. */ + +#define UPDATE_OFFSET (backtrace_byte_offset = pc - bytestr_data - 1) + DEFUN ("byte-code", Fbyte_code, Sbyte_code, 3, 3, 0, doc: /* Function used internally in byte-compiled code. The first argument, BYTESTR, is a string of byte code; @@ -618,6 +622,7 @@ #define DEFINE(name, value) LABEL (name) , op -= Bcall; docall: { + UPDATE_OFFSET; DISCARD (op); #ifdef BYTE_CODE_METER if (byte_metering_on && SYMBOLP (TOP)) @@ -1448,7 +1453,7 @@ #define DEFINE(name, value) LABEL (name) , unbind_to (count, Qnil); error ("binding stack not balanced (serious byte compiler bug)"); } - + backtrace_byte_offset = -1; Lisp_Object result = TOP; SAFE_FREE (); return result; diff --git a/src/eval.c b/src/eval.c index 959adea646..e4451aa96c 100644 --- a/src/eval.c +++ b/src/eval.c @@ -137,6 +137,13 @@ backtrace_args (union specbinding *pdl) return pdl->bt.args; } +static int +backtrace_bytecode_offset (union specbinding *pdl) +{ + eassert (pdl->kind == SPECPDL_BACKTRACE); + return pdl->bt.bytecode_offset; +} + static bool backtrace_debug_on_exit (union specbinding *pdl) { @@ -2149,6 +2156,11 @@ record_in_backtrace (Lisp_Object function, Lisp_Object *args, ptrdiff_t nargs) specpdl_ptr->bt.function = function; current_thread->stack_top = specpdl_ptr->bt.args = args; specpdl_ptr->bt.nargs = nargs; + if (backtrace_byte_offset > 0) { + union specbinding *nxt = backtrace_top (); + if (backtrace_p (nxt) && nxt->kind == SPECPDL_BACKTRACE) + nxt->bt.bytecode_offset = backtrace_byte_offset; + } grow_specpdl (); return count; @@ -3650,6 +3662,10 @@ backtrace_frame_apply (Lisp_Object function, union specbinding *pdl) if (backtrace_debug_on_exit (pdl)) flags = list2 (QCdebug_on_exit, Qt); + int off = backtrace_bytecode_offset (pdl); + if (off > 0) + flags = Fcons (QCbytecode_offset, Fcons (make_fixnum (off), flags)); + if (backtrace_nargs (pdl) == UNEVALLED) return call4 (function, Qnil, backtrace_function (pdl), *backtrace_args (pdl), flags); else @@ -4237,6 +4253,7 @@ syms_of_eval (void) defsubr (&Sfetch_bytecode); defsubr (&Sbacktrace_debug); DEFSYM (QCdebug_on_exit, ":debug-on-exit"); + DEFSYM (QCbytecode_offset, ":bytecode-offset"); defsubr (&Smapbacktrace); defsubr (&Sbacktrace_frame_internal); defsubr (&Sbacktrace_frames_from_thread); diff --git a/src/lisp.h b/src/lisp.h index 3442699088..e92300f4f7 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3230,6 +3230,7 @@ #define DEFVAR_KBOARD(lname, vname, doc) \ Lisp_Object function; Lisp_Object *args; ptrdiff_t nargs; + int bytecode_offset; } bt; }; diff --git a/src/thread.h b/src/thread.h index a09929fa44..b5e3f0f9c5 100644 --- a/src/thread.h +++ b/src/thread.h @@ -103,6 +103,11 @@ #define specpdl (current_thread->m_specpdl) union specbinding *m_specpdl_ptr; #define specpdl_ptr (current_thread->m_specpdl_ptr) + /* The offset of the current op of the byte-code function being + executed. */ + int m_backtrace_byte_offset; +#define backtrace_byte_offset (current_thread->m_backtrace_byte_offset) + /* Depth in Lisp evaluations and function calls. */ intmax_t m_lisp_eval_depth; #define lisp_eval_depth (current_thread->m_lisp_eval_depth) --=-=-=--