unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* eassert always aborts in eval.c in an optimized build
@ 2024-10-27  8:50 Eli Zaretskii
  2024-10-27 17:57 ` Paul Eggert
  0 siblings, 1 reply; 6+ messages in thread
From: Eli Zaretskii @ 2024-10-27  8:50 UTC (permalink / raw)
  To: Paul Eggert; +Cc: emacs-devel

Something is wrong with our definition/use of eassert in eval.c when
Emacs is compiled with optimizations and with --enable-checking: all
the functions in eval.c that assert pdl->kind's value are compiled
into code that always aborts.  Here's one example:

  Lisp_Object
  backtrace_function (union specbinding *pdl)
  {
    eassert (pdl->kind == SPECPDL_BACKTRACE);
    return pdl->bt.function;
  }

  (gdb) disassemble backtrace_function
  Dump of assembler code for function backtrace_function:
     0x000055880a6b9e0f <+0>:     push   %rax
     0x000055880a6b9e10 <+1>:     pop    %rax
     0x000055880a6b9e11 <+2>:     mov    $0x72,%edx
     0x000055880a6b9e16 <+7>:     lea    0x31821b(%rip),%rsi        # 0x55880a9d2038
     0x000055880a6b9e1d <+14>:    lea    0x3186b4(%rip),%rdi        # 0x55880a9d24d8
     0x000055880a6b9e24 <+21>:    push   %rax
     0x000055880a6b9e25 <+22>:    call   0x55880a6b51f6 <die>
  End of assembler dump.

It sounds like GCC decided that pdl->kind == SPECPDL_BACKTRACE is
_always_ false, and that suppress_checking is also always false.  But
why does it decide that?

This means one cannot build an optimized Emacs with --enable-checking
and be able to invoke xbacktrace from GDB, so we should fix this ASAP.

It goes without saying that other uses of eassert elsewhere in Emacs
do appear to work, and the code generated for them does test the
conditions.

Thanks.



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: eassert always aborts in eval.c in an optimized build
  2024-10-27  8:50 eassert always aborts in eval.c in an optimized build Eli Zaretskii
@ 2024-10-27 17:57 ` Paul Eggert
  2024-10-27 19:26   ` Eli Zaretskii
  2024-10-28  0:34   ` Paul Eggert
  0 siblings, 2 replies; 6+ messages in thread
From: Paul Eggert @ 2024-10-27 17:57 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

On 2024-10-27 01:50, Eli Zaretskii wrote:
> Something is wrong with our definition/use of eassert in eval.c when
> Emacs is compiled with optimizations and with --enable-checking: all
> the functions in eval.c that assert pdl->kind's value are compiled
> into code that always aborts.

A quick look suggests that although the actual code is fine, GDB is 
confused and its "disassemble" and other commands think that the symbol 
"backtrace_function" stands for the address of just part of the 
backtrace_function code, not the address of the function's first 
instruction.

If my guess is right, if you try to debug Emacs with GDB and use 
xbacktrace or similar commands, things will go haywire. You'll see 
symptoms like this:

(gdb) p backtrace_function
$1 = {Lisp_Object (union specbinding *)} 0x6ed5c <backtrace_function>

... whereas the shell command "nm emacs | grep backtrace_function" 
outputs this:

0000000000293cd0 T backtrace_function
000000000006ee78 t backtrace_function.cold
000000000006ed5c t backtrace_function.part.0

... and we can see that GDB has the wrong "backtrace_function".

Does this match the symptoms you're observing?

If my guess is right, GDB should be fixed, and also we should look into 
patching Emacs to work around the GDB bug.



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: eassert always aborts in eval.c in an optimized build
  2024-10-27 17:57 ` Paul Eggert
@ 2024-10-27 19:26   ` Eli Zaretskii
  2024-10-27 19:30     ` Paul Eggert
  2024-10-28  0:34   ` Paul Eggert
  1 sibling, 1 reply; 6+ messages in thread
From: Eli Zaretskii @ 2024-10-27 19:26 UTC (permalink / raw)
  To: Paul Eggert; +Cc: emacs-devel

> Date: Sun, 27 Oct 2024 10:57:21 -0700
> Cc: emacs-devel@gnu.org
> From: Paul Eggert <eggert@cs.ucla.edu>
> 
> On 2024-10-27 01:50, Eli Zaretskii wrote:
> > Something is wrong with our definition/use of eassert in eval.c when
> > Emacs is compiled with optimizations and with --enable-checking: all
> > the functions in eval.c that assert pdl->kind's value are compiled
> > into code that always aborts.
> 
> A quick look suggests that although the actual code is fine, GDB is 
> confused and its "disassemble" and other commands think that the symbol 
> "backtrace_function" stands for the address of just part of the 
> backtrace_function code, not the address of the function's first 
> instruction.

But then why does xbacktrace always abort?  Are you saying it calls
the part that aborts?

> If my guess is right, if you try to debug Emacs with GDB and use 
> xbacktrace or similar commands, things will go haywire. You'll see 
> symptoms like this:
> 
> (gdb) p backtrace_function
> $1 = {Lisp_Object (union specbinding *)} 0x6ed5c <backtrace_function>
> 
> ... whereas the shell command "nm emacs | grep backtrace_function" 
> outputs this:
> 
> 0000000000293cd0 T backtrace_function
> 000000000006ee78 t backtrace_function.cold
> 000000000006ed5c t backtrace_function.part.0

I see the first and the last of these 3 lines; mo "cold" part.

> ... and we can see that GDB has the wrong "backtrace_function".
> 
> Does this match the symptoms you're observing?

Sounds like that, yes.

> If my guess is right, GDB should be fixed, and also we should look into 
> patching Emacs to work around the GDB bug.

I see this with GDB 12.1 on GNU/Linux and with GDB 15.1 on MS-Windows,
so I'm guessing fixing GDB will not be easy, and there will be many
un-fixed GDB versions around even after GDB is fixed.  We should work
around this in Emacs regardless.

Thanks.



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: eassert always aborts in eval.c in an optimized build
  2024-10-27 19:26   ` Eli Zaretskii
@ 2024-10-27 19:30     ` Paul Eggert
  0 siblings, 0 replies; 6+ messages in thread
From: Paul Eggert @ 2024-10-27 19:30 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

On 2024-10-27 12:26, Eli Zaretskii wrote:

> But then why does xbacktrace always abort?  Are you saying it calls
> the part that aborts?

Yes.


> I see this with GDB 12.1 on GNU/Linux and with GDB 15.1 on MS-Windows,
> so I'm guessing fixing GDB will not be easy, and there will be many
> un-fixed GDB versions around even after GDB is fixed.  We should work
> around this in Emacs regardless.

Yes.



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: eassert always aborts in eval.c in an optimized build
  2024-10-27 17:57 ` Paul Eggert
  2024-10-27 19:26   ` Eli Zaretskii
@ 2024-10-28  0:34   ` Paul Eggert
  2024-10-28 13:49     ` Eli Zaretskii
  1 sibling, 1 reply; 6+ messages in thread
From: Paul Eggert @ 2024-10-28  0:34 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 481 bytes --]

I installed the attached hack to work around what appears to be a GDB 
bug; please give it a try when you have the time.

Although the hack might be needed for other functions marked 
EXTERNALLY_VISIBLE for GDB, I applied it only to the function that you 
reported the GDB bug for. We can apply the hack to the other functions 
later, if we discover they need it. This hack is merely for convenience 
when we debug Emacs with GDB so it's OK to be cautious about applying 
the hack.

[-- Attachment #2: 0001-Work-around-GDB-bug-32313-when-debugging-Emacs-inter.patch --]
[-- Type: text/x-patch, Size: 2104 bytes --]

From ebf3fb9a2295520ef8ce1756086fd9bbd3d04e9e Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Sun, 27 Oct 2024 17:21:23 -0700
Subject: [PATCH] Work around GDB bug 32313 when debugging Emacs internals

Problem reported by Eli Zaretskii in:
https://lists.gnu.org/r/emacs-devel/2024-10/msg00653.html
* src/eval.c (backtrace_function_body): Rename from
backtrace_function, and make it static.
(GDB_FUNCPTR): New macro.
(backtrace_function): New function pointer, for GDB only.
---
 src/eval.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/src/eval.c b/src/eval.c
index 874cf6d868c..3c4999d818c 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -51,7 +51,6 @@ Copyright (C) 1985-1987, 1993-1995, 1999-2024 Free Software Foundation,
 /* These would ordinarily be static, but they need to be visible to GDB.  */
 bool backtrace_p (union specbinding *) EXTERNALLY_VISIBLE;
 Lisp_Object *backtrace_args (union specbinding *) EXTERNALLY_VISIBLE;
-Lisp_Object backtrace_function (union specbinding *) EXTERNALLY_VISIBLE;
 union specbinding *backtrace_next (union specbinding *) EXTERNALLY_VISIBLE;
 union specbinding *backtrace_top (void) EXTERNALLY_VISIBLE;
 
@@ -108,12 +107,21 @@ specpdl_arg (union specbinding *pdl)
   return pdl->unwind.arg;
 }
 
-Lisp_Object
-backtrace_function (union specbinding *pdl)
+static Lisp_Object
+backtrace_function_body (union specbinding *pdl)
 {
   eassert (pdl->kind == SPECPDL_BACKTRACE);
   return pdl->bt.function;
 }
+/* To work around GDB bug 32313
+   <https://sourceware.org/bugzilla/show_bug.cgi?id=32313>
+   make backtrace_function a visible-to-GDB pointer instead of merely
+   being an externally visible function itself.  Declare the pointer
+   first to pacify gcc -Wmissing-variable-declarations.  */
+#define GDB_FUNCPTR(func, resulttype, params) \
+  extern resulttype (*const func) params EXTERNALLY_VISIBLE; \
+  resulttype (*const func) params = func##_body
+GDB_FUNCPTR (backtrace_function, Lisp_Object, (union specbinding *));
 
 static ptrdiff_t
 backtrace_nargs (union specbinding *pdl)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: eassert always aborts in eval.c in an optimized build
  2024-10-28  0:34   ` Paul Eggert
@ 2024-10-28 13:49     ` Eli Zaretskii
  0 siblings, 0 replies; 6+ messages in thread
From: Eli Zaretskii @ 2024-10-28 13:49 UTC (permalink / raw)
  To: Paul Eggert; +Cc: emacs-devel

> Date: Sun, 27 Oct 2024 17:34:57 -0700
> From: Paul Eggert <eggert@cs.ucla.edu>
> Cc: emacs-devel@gnu.org
> 
> I installed the attached hack to work around what appears to be a GDB 
> bug; please give it a try when you have the time.
> 
> Although the hack might be needed for other functions marked 
> EXTERNALLY_VISIBLE for GDB, I applied it only to the function that you 
> reported the GDB bug for. We can apply the hack to the other functions 
> later, if we discover they need it. This hack is merely for convenience 
> when we debug Emacs with GDB so it's OK to be cautious about applying 
> the hack.

Thanks.  I needed to install the same trick for one more function, and
xbacktrace is now working again!



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2024-10-28 13:49 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-27  8:50 eassert always aborts in eval.c in an optimized build Eli Zaretskii
2024-10-27 17:57 ` Paul Eggert
2024-10-27 19:26   ` Eli Zaretskii
2024-10-27 19:30     ` Paul Eggert
2024-10-28  0:34   ` Paul Eggert
2024-10-28 13:49     ` Eli Zaretskii

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).