From unknown Sun Jun 22 00:09:17 2025 X-Loop: help-debbugs@gnu.org Subject: bug#78842: Ferror_message_string sometimes fails to clear prin1-to-string-buffer Resent-From: Pip Cet Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 19 Jun 2025 20:03:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 78842 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: 78842@debbugs.gnu.org X-Debbugs-Original-To: bug-gnu-emacs@gnu.org Received: via spool by submit@debbugs.gnu.org id=B.17503633534449 (code B ref -1); Thu, 19 Jun 2025 20:03:02 +0000 Received: (at submit) by debbugs.gnu.org; 19 Jun 2025 20:02:33 +0000 Received: from localhost ([127.0.0.1]:38479 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1uSLSx-00019T-LR for submit@debbugs.gnu.org; Thu, 19 Jun 2025 16:02:33 -0400 Received: from lists.gnu.org ([2001:470:142::17]:37912) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1uSLSt-00017n-V0 for submit@debbugs.gnu.org; Thu, 19 Jun 2025 16:02:29 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uSLSm-0008Q1-6o for bug-gnu-emacs@gnu.org; Thu, 19 Jun 2025 16:02:20 -0400 Received: from mail-24416.protonmail.ch ([109.224.244.16]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uSLSi-000076-2Q for bug-gnu-emacs@gnu.org; Thu, 19 Jun 2025 16:02:19 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1750363332; x=1750622532; bh=PpyIUjftATz51brwgpZJUsvHSPItjjhYhlDUbyuoJdk=; h=Date:To:From:Subject:Message-ID:Feedback-ID:From:To:Cc:Date: Subject:Reply-To:Feedback-ID:Message-ID:BIMI-Selector: List-Unsubscribe:List-Unsubscribe-Post; b=E7ZrK27VZdoQcmqpgUJYQJcbVFuIxo/mBBwYl981Jnw8s2kz475tUNhw/mO26c7DK /jkJxHf5F7/mHEyw47JQf4xCGhp3oQzjiNtzo1UYDBm58fIdfDgGsXS9udA8JXme7b +NZnB2t507Qqw2M8c2SoWnqz37jIxNKG6IEuXpM+HXx+fGmF6dbPQu8k5NIerjj/pJ smqgmMJtZSyIhyccZxJ8zZ8f86J0MxpTQyB8OoJHYWpmBuKgjRNlc93mBXb9cVUWgF YBtLX58pkoZhdFr9dJ3U4pODTyvNzISdHn/c8icH13eMA6g5qAYIzNi/vGcWvxx26r 7M7MwYI9pIJjA== Date: Thu, 19 Jun 2025 20:02:06 +0000 From: Pip Cet Message-ID: <875xgrqz44.fsf@protonmail.com> Feedback-ID: 112775352:user:proton X-Pm-Message-ID: 3395e4311bcf84a0ea291584a7fc073dad376c19 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Received-SPF: pass client-ip=109.224.244.16; envelope-from=pipcet@protonmail.com; helo=mail-24416.protonmail.ch 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, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Spam-Score: 1.0 (+) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) This is a (hopefully) rare bug which happens to be triggered by a rather exotic test case; see recipe below. During ordinary operation, Ferror_message_string calls print_error_message, then grabs the prin1-to-string buffer's contents and erases it. Sometimes, however, print_error_message throws an error after writing some text ("peculiar error: error", in this case) to the buffer. Currently, Ferror_message_string fails to erase the buffer in this case (it doesn't catch or unwind-protect anything), so the *next* call to prin1-to-string will return the "peculiar error: error" string before the actual output. This test in print-tests.el: (print-tests--deftest error-message-string-circular () (let ((err (list 'error))) (setcdr err err) (should-error (error-message-string err) :type 'circular-list))) triggers this condition; the next prin1-to-string run after this test will include the "peculiar error: error" string (twice, in this case, because print-tests--deftests defines two tests, one for cl-prin1 and one for prin1; they produce one copy each). Recipe: 1. emacs -Q -l test/src/print-tests.el 2. M-x ert RET RET Output: F print-bignum (ert-test-failed ((should (equal (print-tests--prin1-to-string val) str)) :form (equal "peculiar error: errorpeculiar error: error9999999999999999999999999= 99999999" "999999999999999999999999999999999") :value nil :explanation (arrays-of-different-length 75 33 =09=09=09=09 "peculiar error: errorpeculiar error: error999999999999999999= 999999999999999" =09=09=09=09 "999999999999999999999999999999999" =09=09=09=09 first-mismatch-at 0))) Is this proposed patch okay for master? While there are additional specpdl allocations in Ferror_message_string, there are no new allocations in the (error STRING) case mentioned in the comment. No changes in print_error_message, which I think is important because we want that function to produce its output in chunks. Should we also modify the error-message-string-circular test to check that a subsequent prin1-to-string doesn't produce extra output? >From c317ec081667d8a53647fa6844880cc00d26b50a Mon Sep 17 00:00:00 2001 From: Pip Cet Subject: [PATCH] Avoid extra output in Vprin1_to_string_buffer * src/print.c (erase_prin1_to_string_buffer): New. (Ferror_message_string): Catch errors thrown in 'print_error_message'. --- src/print.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/print.c b/src/print.c index b6ee89478c7..fdb8cc8863c 100644 --- a/src/print.c +++ b/src/print.c @@ -1023,6 +1023,14 @@ debug_format (const char *fmt, Lisp_Object arg) } =20 =0C +/* Erase the Vprin1_to_string_buffer, potentially switching to it. */ +static void +erase_prin1_to_string_buffer (void) +{ + set_buffer_internal (XBUFFER (Vprin1_to_string_buffer)); + Ferase_buffer (); +} + DEFUN ("error-message-string", Ferror_message_string, Serror_message_strin= g, 1, 1, 0, doc: /* Convert an error value (ERROR-SYMBOL . DATA) to an error me= ssage. @@ -1030,9 +1038,6 @@ DEFUN ("error-message-string", Ferror_message_string,= Serror_message_string, error message is constructed. */) (Lisp_Object obj) { - struct buffer *old =3D current_buffer; - Lisp_Object value; - /* If OBJ is (error STRING), just return STRING. That is not only faster, it also avoids the need to allocate space here when the error is due to memory full. */ @@ -1042,15 +1047,13 @@ DEFUN ("error-message-string", Ferror_message_strin= g, Serror_message_string, && NILP (XCDR (XCDR (obj)))) return XCAR (XCDR (obj)); =20 + specpdl_ref count =3D SPECPDL_INDEX (); + record_unwind_current_buffer (); + record_unwind_protect_void (erase_prin1_to_string_buffer); print_error_message (obj, Vprin1_to_string_buffer, 0, Qnil); =20 set_buffer_internal (XBUFFER (Vprin1_to_string_buffer)); - value =3D Fbuffer_string (); - - Ferase_buffer (); - set_buffer_internal (old); - - return value; + return unbind_to (count, Fbuffer_string ()); } =20 /* Print an error message for the error DATA onto Lisp output stream --=20 2.48.1