Re: [rfa] Attach vsyscall support for GNU/Linux

Daniel Jacobowitz
2004-10-24T23:16:38Z

[Roland, question for you a bit of the way down...]

On Sun, Oct 24, 2004 at 10:54:45PM +0200, Mark Kettenis wrote:
> Date: Sun, 24 Oct 2004 14:53:45 -0400
> From: Daniel Jacobowitz <drow@false.org>
>
> This patch, based on a patch Andrew posted earlier this year, connects
> vsyscall support to the inferior_created observer.
>
> As before, I have adjusted the i386-linux sigtramp code to recognize
> the names of the kernel trampolines (both of them this time - I forgot
> the RT case when I first did this). And I have adjusted the i386
> target to recognize signal trampolines before searching for DWARF-2
> unwind information, as previously discussed. Other architectures which
> now have a vsyscall DSO may need to make the same change.
>
> I still don't get it. What exactly was the purpose of adding the
> vsyscall DSO if we're not using the DWARF CFI it contains. Can't the
> people who dreamt up this wonderful mechanism fix their implementation
> such that it doesn't contain any useless DWARF CFI? I'm a bit
> reluctant to approve this since it'll probably mean that it never get
> fixed properly :-(.

If you mean, why add support for it to GDB: so that we can actually
backtrace from the _other_ things in the vsyscall DSO besides signal
handlers. The one I'm interested in is the __kernel_vsyscall stub.
I could care less about having CFI for the signal trampolines.

If you mean the purpose of creating it in the first place, it was added
for performance. The CFI was added for run-time unwinders, and
generally works. I haven't spent enough time analyzing the problem,
but I think it only generally works - if the off-by-one doesn't change
the unwind data, which it rarely does in practice.

There's no way in DWARF CFI to express the difference between return PC
is "virtual call site" address (as here) and return PC is "resume
address, following call site" (as normally). It's not amenable to
being expressed, because it is more a property of the call site, but
the unwind information is a property of the call destination.

I just don't think this problem is solvable within the existing CFI.
I don't know whether it is solvable by extending DWARF. Just to make
sure I'm on the right page, I'll recap one instance of why GDB needs to
know it's found a signal handler.

Here's __kernel_rt_sigreturn (starts at 0xffffe440).
ffffe43f: 90 nop
ffffe440: b8 ad 00 00 00 mov $0xad,%eax
ffffe445: cd 80 int $0x80

Here's the unwind information:
000000c4 00000044 00000084 FDE cie=00000044 pc=ffffe43f..ffffe447
DW_CFA_def_cfa_expression (DW_OP_breg4: 188; DW_OP_deref)
DW_CFA_expression: r0 (DW_OP_breg4: 204)
DW_CFA_expression: r1 (DW_OP_breg4: 200)
DW_CFA_expression: r2 (DW_OP_breg4: 196)
DW_CFA_expression: r3 (DW_OP_breg4: 192)
DW_CFA_expression: r5 (DW_OP_breg4: 184)
DW_CFA_expression: r6 (DW_OP_breg4: 180)
DW_CFA_expression: r7 (DW_OP_breg4: 176)
DW_CFA_expression: r8 (DW_OP_breg4: 216)
DW_CFA_nop

This is accurate. It correctly locates the saved values of all
registers. However, this is the frame_address_in_block problem; if the
first instruction of a function generates a synchronous signal, then
the restored value of r8 (the PC) will point to the first byte of the
function. GDB will use the unwind information for the previous
function.

I bet you could reproduce the corresponding problem by an extremely
signal-heavy stress test using NPTL and asynchronous cancellation.
Roland, am I missing something? Won't we go off into never-never land
if we're at the first instruction of a function call when a signal is
received and we try to do a forced unwind?

Unwinding bugs aside, I think it's valuable for GDB to know that it is
at a signal trampoline. I think the custom display in backtrace is
valuable. That means we should look for signal handlers before looking
for CFI. For NPTL that value judgement would fall the other way - not
having to special-case signal handlers is a clear win.

> But there's another reason why I'm against this patch. It changes the
> order of the unwinders for all the other i386 targets too. Please
> find a way to do this such that it affect Linux only.
>
> Sorry, I didn't realize this before...

OK, if the rest of the patch reaches consensus I will try to figure out
how to do this. It will probably just require conditional action based
on the osabi enum. Not hard.

--
Daniel Jacobowitz