This is the mail archive of the libc-hacker@sourceware.cygnus.com mailing list for the glibc project.
Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Hi Ulrich,
I think the current definitions of prgregset_t & prfpregset_t in
sysdeps/unix/sysv/linux/i386/sys/procfs.h are somewhat misleading:
/* Register sets. Linux has different names. */
typedef gregset_t prgregset_t;
typedef fpregset_t prfpregset_t;
This suggests that the register layout for prgregset_t is identical to
the register layout used for the gregset_t type. However, in the
current implementation of the thread_db support for Linuxthreads in
GDB, this is not the case. GDB uses ptrace() to get the registers of
a particular thread, and ptrace() returns the registers in `struct
user' format (struct user_regs_struct, defined in sys/user.h), which
is AKA elf_gregset_t (defined in sys/elf.h).
So the question is, did you really mean to use gregset_t for passing
around register values in the thread_db interface? I suspect you did
not and in that case, the definition:
typedef elf_gregset_t prgregset_t;
typedef elf_fpregset_t prfregset_t;
would make more sense.
Note that there might be some real danger here too, since:
sizeof (elf_gregset_t) < sizeof (gregset_t)
Also look at the following fragment from
linuxthreads_db/td_thr_getfpregs.c:
td_err_e
td_thr_getfpregs (const td_thrhandle_t *th, prfpregset_t *regset)
{
struct _pthread_descr_struct pds;
LOG (__FUNCTION__);
/* We have to get the state and the PID for this thread. */
if (ps_pdread (th->th_ta_p->ph, th->th_unique, &pds,
sizeof (struct _pthread_descr_struct)) != PS_OK)
return TD_ERR;
/* If the thread already terminated we return all zeroes. */
if (pds.p_terminated)
memset (regset, '\0', sizeof (*regset));
In the current situation (due to the weird definition of fpregset_t),
we have effectively:
struct _fpstate **regset;
So sizeof (*regset) == 4, and only the first part of the structure is
zeroed out.
The source of this mess is obvious: GDB uses the gregset_t type where
it actually should use `struct user_regs_struct'. Remember HJ's
complaint about GDB compilation problems? You told him to use
elf_gregset_t (which is allright since that is just another way of
viewing `struct user_regs_struct'). So you see that GDB is really
using the `struct user' layout instead of the sigcontext layout.
Mark
PS I'm working on getting this fixed in GDB (the official one, not
HJ's hacked version).
PPS sys/{elf.h, procfs.h, user.h} contain some really misleading
comments. I'll try to come up with something better.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |