[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [libunwind] problem unwinding signal handler on HPUX
From: |
Rob Faught |
Subject: |
Re: [libunwind] problem unwinding signal handler on HPUX |
Date: |
Mon, 10 Nov 2003 15:52:37 -0500 |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.2.1) Gecko/20010901 |
David Mosberger wrote:
On Tue, 04 Nov 2003 19:06:02 -0500, Rob Faught <address@hidden> said:
Rob> Hello David, It seems that the third argument to a signal
Rob> handler is not a pointer to a full (48640 byte)
Rob> ucontext_t. That is, sizeof(ucontext_t) is much larger than the
Rob> data pushed on the stack. When ia64_uc_access_reg copies the
Rob> ucontext its src pointer falls off the top of the stack with
Rob> bad results. Instead grab the size field out of the ucontext_t
Rob> and use that.
Something is fishy here. ucontext_t is declared as:
typedef struct sigcontext mcontext_t;
typedef struct ucontext
{
union
{
mcontext_t _mc;
struct
{
unsigned long _pad[_SC_GR0_OFFSET/8];
struct ucontext *_link; /* this should overlay sc_gr[0] */
}
_uc;
}
_u;
}
ucontext_t;
so it is exactly as big as the "struct sigcontext" you get from the
kernel. Can you provide a test-case that's failing for you?
--david
_______________________________________________
libunwind mailing list
address@hidden
http://linux.hpl.hp.com/cgi-bin/mailman/listinfo/libunwind
I don't understand what is going on either. It just seems that the
structure pushed on the stack is not as large as a ucontext_t. A
mcontext_t is defined in include/machine/sys/newsig.h as:
typedef struct {
__opaque128_t __mc_opaque[2976];
} __mcontext_t;
The size of ucontext_t should be:
2976 * 16 + 1024(size of misc header + padding) = 48640 (0xbe00) bytes
The test below prints this as the sizeof(ucontext_t), but that is not
the size of the data on the stack. Both the size field in the ucontext_t
and the difference in the stack addresses agree that it is not.
-------------------------------------------------------------------------
#include <stdlib.h>
#include <signal.h>
#include <alloca.h>
/* compile
/opt/aCC/bin/aCC +DD64 -g +noobjdebug testsig.cxx -o testsig
*/
typedef void (*sigh)(int);
void *diff;
void handler(int s, int code, ucontext_t *sc)
{
printf("handler %d code=%d sc=%p\n", s, code, sc);
printf("uc_size=%lx sizeof(ucontext_t)=%lx sizeof(sigcontext)=%lx
diff=%lx\n",
sc->__uc_misc.__uc_size, sizeof(ucontext_t), sizeof(struct sigcontext),
(char *)diff-(char *)sc);
return;
}
void recur(int r)
{
if (r)
recur(--r);
else
{
diff = alloca(8);
printf("before raise %p\n",diff);
raise(2);
}
}
int main(int argc, char *argv[])
{
signal(SIGINT, (sigh)handler);
recur(5);
return 0;
}
---------------------------------------------------------------------
[hptarg:190] testsig
before raise 9ffffffffffff4d0
handler 2 code=0 sc=9fffffffffffa600
uc_size=4e00 sizeof(ucontext_t)=be00 sizeof(sigcontext)=be00 diff=4ed0
---------------------------------------------------------------------
The problem occurs when ia64_uc_access_reg tries to read the 0xbe00
bytes starting at 9fffffffffffa600. I get read errors around
0xa00000000000000.
My earlier suggestion for a fix is incomplete. I didn't change all the
instances of sizeof(ucontext_t) in the file. It also doesn't allow me to
backtrace over all my signal handler examples. One example has an
unbound user thread for which I am not able to get a complete backtrace.
Rob