This is the mail archive of the gdb@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: gdb support for Linux vsyscall DSO


   Date: Sat, 10 May 2003 13:27:20 -0700
   From: Roland McGrath <roland@redhat.com>

   > The run-time dynamic linker's data structures usually are intact, but
   > a fall-back mechanism wouldn't hurt I guess.

   The stack is usually intact too. ;-) It would not be the end of the world
   to rely on the dynamic linker's data structures.  In practice, they are
   intact and people don't use the vsyscall entrypoint in statically linked
   programs.  But I would rather consider *that* the fallback to be used in
   remote situations where the kernel inquiry mechanism isn't available.  If
   there is a kernel inquiry mechanism, it will always be correct.  If there
   are dynamic linker data structures at all, they might be bogus so you don't
   want to use them preferentially.

Careless thinking of me; of course one should prefer the most reliable
method.  I fully agree with you here.

   > Note that symbols from the vsyscall would be very helpful to the user.

   Surely.  But lack thereof doesn't cripple the user the way failure to
   unwind the frame does, so it's not the highest priority.  That's all I said.

   > There is also an issue with signal trampolines.  GDB needs to be able
   > to recognize them in order to support stepping over functions when a
   > signal arrives.  

   I don't think I know exactly what you mean here.  Is there a special case
   for signal frames aside from just knowing how to unwind them properly?
   (The only other specialness I am aware of is "<signal handler called>",
   which with normal unwind info would show __kernel_sigreturn instead.)

There is some special handling for signal trampolines in
infrun.c:handle_inferior_event().  Beware!  Dragons can still be found
in that function.  However, it seems the bit of code I'm talking about
is there for targets that don't known how to properly unwind signal
frames :-).

There is also the issue of unwinding interrupted frames vs. called
frames, where we substract 1 from the return address to get an address
in the middle of the call instruction that is in progress.  But rth
has taken care of that.

   > I proposed Richard Henderson to add a special DWARF CFI augmentation to
   > mark __kernel_sigreturn and __kernel_rt_sigreturn as signal trampolines.
   > That would allow me to recognize them without knowing their names.

   The code I have seen looks at the instruction sequence to match the
   expected system call (using "int $0x80").  All extant Linux kernels still
   have those same exact instruction sequences (as libc's __restore and
   __restore_rt).  So this will continue to work, ugly as it is.  Not that we
   shouldn't address it more cleanly, but I don't think it's in fact breaking
   anything at this very moment.

   rth has added unwind info to the __kernel_{rt_,}sigreturn vsyscall code.
   These describe unwinding the signal frame to restore all the registers to
   the state that was interrupted by the signal (though not the processor
   flags word, I dunno if i386 DWARF2 format can do that--you'd only need that
   if you wanted to roll back the signal handling frame as if it had never
   happened at all, not just to unwind past it or examine the frame's state).  

Restoring %eflags is certainly possible.  Making GDB actually pop the
signal trampoline frame should work, but could lead to "interesting"
behaviour.  I mean, the kernel will still think the program has taken
a signal.  Hmm, looking at both the FreeBSD and Linux kernels it seems
as if only the signal mask might be incorrect.

   > Relying on the dynamic linker's data structures certainly seems
   > attractive to me as an additional method since it works independently
   > of the remote protocol.

   Agreed.  I was vaguely hoping that someone would have a brilliant idea
   that is both remote-friendly and as robust as the kernel-specific
   backend solutions, but I don't think there is one possible.

Well, for processes started by GDB we can read the auxiliary vector
from the pristine stack, but that doesn't work for attached-to
processes.

   > To avoid kludging around one could:

   These are the obvious suggestions.  I am very hesitant to change
   the exposed structures; frankly, those two will probably never
   change again.  The dynamic tag would be a convenient one, but would
   require an ld change and to be sure your kernel was built by a new
   enough ld; that is impractical.

Well, extending the structure shouldn't pose a problem, although there
is some risk.  The origional link.h contained the following comment:

   /* Structure describing...

   ...

   This data structure might change in future, if necessary.  User-level
   programs must avoid defining objects of this type.  */

But those last two sentences have been removed from the link.h that's
actually installed.

   Exposing some way to get the l_phdr pointer is very reasonable.  An
   idea that doesn't raise many of the issues of changing the public
   `struct link_map' layout is export an internal symbol giving
   offsetof (struct link_map, l_phdr).  That is still sort of a kludge
   if you ask me.  But it shouldn't cause many problems in practice.

Given that we know where the dynamic section is from l_ld, I think we
can figure out all we need to know from there.  I used the linker
script from Linux 2.5.69 to generate a vsyscall-int80.so, and I'm
seeing the location of all relevant sections in the symbol table.  Is
it possible to re-order the sections such that .dynamic comes a bit
earlier than now?  In that case (l_ld & 0xfffff000) would almost
certainly be the address of the ELF header.

Mark


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]