gdb/arm: Fix backtrace for pthread_cond_timedwait
authorJan Kratochvil <jan.kratochvil@redhat.com>
Sat, 1 Apr 2023 13:42:57 +0000 (15:42 +0200)
committerJan Kratochvil <jan.kratochvil@redhat.com>
Sat, 1 Apr 2023 13:42:57 +0000 (15:42 +0200)
commit3026cdbdde0e1937f811b52ba18fe3fbb1419ef9
tree8ba5b6f1f0445eb216851da8382eda66a1c6a6c2
parenta3424b707737ede8c5823cb27c896b12fe94471c
gdb/arm: Fix backtrace for pthread_cond_timedwait

GDB expected PC should point right after the SVC instruction when the
syscall is active. But some active syscalls keep PC pointing to the SVC
instruction itself.

This leads to a broken backtrace like:
 Backtrace stopped: previous frame identical to this frame (corrupt stack?)
 #0  0xb6f8681c in pthread_cond_timedwait@@GLIBC_2.4 () from /lib/arm-linux-gnueabihf/libpthread.so.0
 #1  0xb6e21f80 in ?? ()

The reason is that .ARM.exidx unwinder gives up if PC does not point
right after the SVC (syscall) instruction. I did not investigate why but
some syscalls will point PC to the SVC instruction itself. This happens
for the "futex" syscall used by pthread_cond_timedwait.

That normally does not matter as ARM prologue unwinder gets called
instead of the .ARM.exidx one. Unfortunately some glibc calls have more
complicated prologue where the GDB unwinder fails to properly determine
the return address (that is in fact an orthogonal GDB bug). I expect it
is due to the "vpush" there in this case but I did not investigate it more:

Dump of assembler code for function pthread_cond_timedwait@@GLIBC_2.4:
   0xb6f8757c <+0>:     push    {r4, r5, r6, r7, r8, r9, r10, r11, lr}
   0xb6f87580 <+4>:     mov     r10, r2
   0xb6f87584 <+8>:     vpush   {d8}

Regression tested on armv7l kernel 5.15.32-v7l+ (Raspbian 11).

Approved-By: Luis Machado <luis.machado@arm.com>
gdb/arm-tdep.c
gdb/testsuite/gdb.arch/arm-pthread_cond_timedwait-bt.c [new file with mode: 0644]
gdb/testsuite/gdb.arch/arm-pthread_cond_timedwait-bt.exp [new file with mode: 0644]