Bug 30102 - [gdb/tdep, amd64] Disable i386 unwinders
Summary: [gdb/tdep, amd64] Disable i386 unwinders
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: tdep (show other bugs)
Version: HEAD
: P2 minor
Target Milestone: 14.1
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-02-09 14:24 UTC by Tom de Vries
Modified: 2023-02-11 08:05 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tom de Vries 2023-02-09 14:24:36 UTC
As mentioned here ( https://sourceware.org/pipermail/gdb-patches/2023-February/196724.html ), for i386 we have these unwinders:
...
$ gdb -q -batch -ex "set arch i386" -ex "maint info frame-unwinders"
The target architecture is set to "i386".
dummy                   DUMMY_FRAME
dwarf2 tailcall         TAILCALL_FRAME
inline                  INLINE_FRAME
i386 epilogue           NORMAL_FRAME
dwarf2                  NORMAL_FRAME
dwarf2 signal           SIGTRAMP_FRAME
i386 stack tramp        NORMAL_FRAME
i386 sigtramp           SIGTRAMP_FRAME
i386 prologue           NORMAL_FRAME
...
and for amd64:
...
$ gdb -q -batch -ex "set arch i386:x86-64" -ex "maint info frame-unwinders"
The target architecture is set to "i386:x86-64".
dummy                   DUMMY_FRAME
dwarf2 tailcall         TAILCALL_FRAME
inline                  INLINE_FRAME
python                  NORMAL_FRAME
amd64 epilogue          NORMAL_FRAME
i386 epilogue           NORMAL_FRAME
dwarf2                  NORMAL_FRAME
dwarf2 signal           SIGTRAMP_FRAME
amd64 sigtramp          SIGTRAMP_FRAME
amd64 prologue          NORMAL_FRAME
i386 stack tramp        NORMAL_FRAME
i386 sigtramp           SIGTRAMP_FRAME
i386 prologue           NORMAL_FRAME
...

So, why are the i386 unwinders there for amd64?

I recently played around with disabling or moving the "amd64 epilogue" unwinder, and while investigating the effect of that, I came across a failure that was due to the "i386 epilogue" unwinder becoming active and giving the wrong answer, which suggest that the i386 unwinders shouldn't be there for amd64.

Using this tentative patch:
...
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 580664d2ce5..8dccae633f7 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -8613,7 +8613,8 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arc
hes)
      appended to the list first, so that it supercedes the DWARF
      unwinder in function epilogues (where the DWARF unwinder
      currently fails).  */
-  frame_unwind_append_unwinder (gdbarch, &i386_epilogue_frame_unwind);
+  if (info.bfd_arch_info->bits_per_word == 32)
+    frame_unwind_append_unwinder (gdbarch, &i386_epilogue_frame_unwind);
 
   /* Hook in the DWARF CFI frame unwinder.  This unwinder is appended
      to the list before the prologue-based unwinders, so that DWARF
@@ -8792,9 +8793,12 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *ar
ches)
     tdep-> bnd0_regnum = -1;
 
   /* Hook in the legacy prologue-based unwinders last (fallback).  */
-  frame_unwind_append_unwinder (gdbarch, &i386_stack_tramp_frame_unwind);
-  frame_unwind_append_unwinder (gdbarch, &i386_sigtramp_frame_unwind);
-  frame_unwind_append_unwinder (gdbarch, &i386_frame_unwind);
+  if (info.bfd_arch_info->bits_per_word == 32)
+    {
+      frame_unwind_append_unwinder (gdbarch, &i386_stack_tramp_frame_unwind);
+      frame_unwind_append_unwinder (gdbarch, &i386_sigtramp_frame_unwind);
+      frame_unwind_append_unwinder (gdbarch, &i386_frame_unwind);
+    }
 
   /* If we have a register mapping, enable the generic core file
      support, unless it has already been enabled.  */
...
we have for i386 as before, and for amd64:
...
$ gdb -q -batch -ex "set arch i386:x86-64" -ex "maint info frame-unwinders"
The target architecture is set to "i386:x86-64".
dummy                   DUMMY_FRAME     
dwarf2 tailcall         TAILCALL_FRAME  
inline                  INLINE_FRAME    
python                  NORMAL_FRAME    
amd64 epilogue          NORMAL_FRAME    
dwarf2                  NORMAL_FRAME    
dwarf2 signal           SIGTRAMP_FRAME  
amd64 sigtramp          SIGTRAMP_FRAME  
amd64 prologue          NORMAL_FRAME    
...
Comment 1 Tom de Vries 2023-02-09 15:21:38 UTC
(In reply to Tom de Vries from comment #0)
> Using this tentative patch:

Passes testing on amd64/-m64.
Comment 2 Tom de Vries 2023-02-09 22:02:32 UTC
(In reply to Tom de Vries from comment #1)
> (In reply to Tom de Vries from comment #0)
> > Using this tentative patch:
> 
> Passes testing on amd64/-m64.

Likewise for amd64/-m32.
Comment 4 Sourceware Commits 2023-02-11 08:04:56 UTC
The master branch has been updated by Tom de Vries <vries@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=af0d0f34d8bf7482e598308b54e7ba0ae9b0c349

commit af0d0f34d8bf7482e598308b54e7ba0ae9b0c349
Author: Tom de Vries <tdevries@suse.de>
Date:   Sat Feb 11 09:04:51 2023 +0100

    [gdb/tdep] Don't use i386 unwinder for amd64
    
    For i386 we have these unwinders:
    ...
    $ gdb -q -batch -ex "set arch i386" -ex "maint info frame-unwinders"
    The target architecture is set to "i386".
    dummy                   DUMMY_FRAME
    dwarf2 tailcall         TAILCALL_FRAME
    inline                  INLINE_FRAME
    i386 epilogue           NORMAL_FRAME
    dwarf2                  NORMAL_FRAME
    dwarf2 signal           SIGTRAMP_FRAME
    i386 stack tramp        NORMAL_FRAME
    i386 sigtramp           SIGTRAMP_FRAME
    i386 prologue           NORMAL_FRAME
    ...
    and for amd64:
    ...
    $ gdb -q -batch -ex "set arch i386:x86-64" -ex "maint info frame-unwinders"
    The target architecture is set to "i386:x86-64".
    dummy                   DUMMY_FRAME
    dwarf2 tailcall         TAILCALL_FRAME
    inline                  INLINE_FRAME
    python                  NORMAL_FRAME
    amd64 epilogue          NORMAL_FRAME
    i386 epilogue           NORMAL_FRAME
    dwarf2                  NORMAL_FRAME
    dwarf2 signal           SIGTRAMP_FRAME
    amd64 sigtramp          SIGTRAMP_FRAME
    amd64 prologue          NORMAL_FRAME
    i386 stack tramp        NORMAL_FRAME
    i386 sigtramp           SIGTRAMP_FRAME
    i386 prologue           NORMAL_FRAME
    ...
    
    ISTM me there's no reason for the i386 unwinders to be there for amd64.
    
    Furthermore, there's a generic need to play around with enabling and disabling
    unwinders, see PR8434.  Currently, that's only available for both the dwarf2
    unwinders at once using "maint set dwarf unwinders on/off".
    
    If I manually disable the "amd64 epilogue" unwinder, the "i386 epilogue"
    unwinder becomes active and gives the wrong answer, while I'm actually
    interested in the result of the dwarf2 unwinder.  Of course I can also
    manually disable the "i386 epilogue", but I take the fact that I have to do
    that as evidence that on amd64, the "i386 epilogue" is not only unnecessary,
    but in the way.
    
    Fix this by only adding the i386 unwinders if
    "info.bfd_arch_info->bits_per_word == 32".
    
    Note that the x32 abi (x86_64/-mx32):
    - has the same unwinder list as amd64 (x86_64/-m64) before this commit,
    - has info.bfd_arch_info->bits_per_word == 64, the same as amd64, and
      consequently,
    - has the same unwinder list as amd64 after this commit.
    
    Tested on x86_64-linux, -m64 and -m32.  Not tested with -mx32.
    
    Reviewed-By: John Baldwin <jhb@freebsd.org>
    
    PR tdep/30102
    Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30102
Comment 5 Tom de Vries 2023-02-11 08:05:49 UTC
Fixed.